react-listing-engine 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # react-listing-engine
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - `/styled`: one unified, sticky filter bar on all breakpoints instead of a separate mobile header + "Filters" bottom sheet. Search + filters render inline; on mobile the bar is a single horizontally-scrolling row (dashboard-style) so filters stay visible rather than hiding behind a button. Removes the `MobileHeader`; the `BottomSheet` primitive is still exported but no longer used by the layout. The `search` box and the optional action now live in the filter bar (`mobileAction` is rendered there on all breakpoints).
8
+
9
+ ## 0.4.1
10
+
11
+ ### Patch Changes
12
+
13
+ - Fix: an `iconUrl`-driven marker layer (e.g. nearby businesses) crashed the map. `resolveMarkerContent` passed the `google.maps.marker.PinElement` INSTANCE as an `AdvancedMarkerElement`'s `content`, but the instance is not a DOM node at runtime (the `@types` wrongly declare it `extends HTMLElement`) -- so Google's marker mount called `IntersectionObserver.observe()` on a non-Element and threw. It now passes the PinElement's `.element`.
14
+
3
15
  ## 0.4.0
4
16
 
5
17
  ### Minor Changes
@@ -0,0 +1,2 @@
1
+ "use client";
2
+ import{A as X,B as Y,h as K,i as D,j as W,k as H,l as $,n as O,p as z,q as U,s as N,u as Z,v as q,x as G,y as J,z as Q}from"./chunk-R3FX2V3N.js";import{useEffect as pe,useRef as de}from"react";function j(e,r){let t=N(),i=de(r);i.current=r,pe(()=>t.on(e,o=>i.current(o)),[t,e])}function g(e){return typeof e!="number"?e:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(e)}import{Fragment as me,jsx as l,jsxs as ee}from"react/jsx-runtime";function ce(e){return e?"rle-card rle-card--selected":"rle-card"}function C({item:e,selected:r,onSelect:t}){let i=e??{},o=ce(r),a=ee(me,{children:[i.imageUrl?l("img",{src:i.imageUrl,alt:i.title??"",className:"rle-card-media"}):l("div",{className:"rle-card-media rle-card-media--placeholder","aria-hidden":"true"}),ee("div",{className:"rle-card-body",children:[i.title&&l("span",{className:"rle-card-title",children:i.title}),i.subtitle&&l("span",{className:"rle-card-address",children:i.subtitle}),i.badge&&l("div",{className:"rle-card-info",children:l("span",{className:"rle-card-info-item",children:i.badge})}),i.price!=null&&l("span",{className:"rle-card-price",children:g(i.price)})]})]});return t?l("button",{type:"button",onClick:t,"aria-pressed":r??!1,className:o,children:a}):l("article",{className:o,children:a})}import{jsx as P,jsxs as te}from"react/jsx-runtime";function I(e){return te("div",{role:"status",className:"rle-empty",children:[te("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:[P("circle",{cx:"11",cy:"11",r:"7"}),P("path",{d:"m21 21-4.3-4.3"})]}),P("p",{className:"rle-empty-title",children:"No results"}),P("p",{className:"rle-empty-hint",children:"Try adjusting your filters or search terms."})]})}import{jsx as ue}from"react/jsx-runtime";function k({children:e}){return ue("div",{className:"rle-filter-panel",children:e})}import{jsx as S,jsxs as ge}from"react/jsx-runtime";function F(e){return S("div",{className:"rle-loading",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((r,t)=>ge("div",{className:"rle-loading-item",children:[S("div",{className:"rle-skeleton",style:{aspectRatio:"4 / 3",width:"100%"}}),S("div",{className:"rle-skeleton",style:{height:16,width:"65%"}}),S("div",{className:"rle-skeleton",style:{height:12,width:"35%"}})]},t))})}import{jsx as ye}from"react/jsx-runtime";function M({point:e}){let r=e.entity??{};return ye("span",{className:"rle-pin",children:r.price!=null?g(r.price):""})}import{jsx as y,jsxs as T}from"react/jsx-runtime";function E({entity:e,onClose:r}){let t=e??{};return T("div",{className:"rle-popup",role:"group","aria-label":"Location details",children:[y("button",{type:"button",onClick:r,"aria-label":"Close",className:"rle-popup-close",children:T("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:[y("path",{d:"M18 6 6 18"}),y("path",{d:"m6 6 12 12"})]})}),T("div",{children:[t.title&&y("div",{className:"rle-card-title",children:t.title}),t.subtitle&&y("div",{className:"rle-card-address",children:t.subtitle}),t.price!=null&&y("div",{className:"rle-card-price",children:g(t.price)})]})]})}import{jsx as fe}from"react/jsx-runtime";function R({count:e,total:r}){let t=r!=null&&r!==e?`${e} of ${r} results`:`${e} results`;return fe("div",{className:"rle-result-header",children:t})}import{jsx as ve}from"react/jsx-runtime";function _({value:e,onChange:r,placeholder:t}){return ve("input",{type:"search",value:e,placeholder:t,onChange:i=>r(i.target.value),"aria-label":t??"Search",className:"rle-input"})}import{jsx as Le}from"react/jsx-runtime";function B({children:e}){return Le("aside",{className:"rle-sidebar",children:e})}import{jsx as he}from"react/jsx-runtime";function A({children:e}){return he("div",{className:"rle-toolbar",children:e})}var re={Card:C,Marker:M,Popup:E,Sidebar:B,FilterPanel:k,Search:_,Empty:I,Loading:F,ResultHeader:R,Toolbar:A};import{jsx as n,jsxs as v}from"react/jsx-runtime";function ie({view:e,onViewChange:r}){return n("nav",{className:"rle-bottom-nav","aria-label":"Listing navigation",children:v("div",{className:"rle-viewtoggle",role:"group","aria-label":"View",children:[v("button",{type:"button",className:`rle-viewtoggle__btn${e==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":e==="list",onClick:()=>r("list"),children:[n(be,{}),"List"]}),v("button",{type:"button",className:`rle-viewtoggle__btn${e==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":e==="map",onClick:()=>r("map"),children:[n(Ne,{}),"Map"]})]})})}function be(){return v("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:[n("line",{x1:"8",y1:"6",x2:"20",y2:"6"}),n("line",{x1:"8",y1:"12",x2:"20",y2:"12"}),n("line",{x1:"8",y1:"18",x2:"20",y2:"18"}),n("line",{x1:"4",y1:"6",x2:"4.01",y2:"6"}),n("line",{x1:"4",y1:"12",x2:"4.01",y2:"12"}),n("line",{x1:"4",y1:"18",x2:"4.01",y2:"18"})]})}function Ne(){return v("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:[n("polygon",{points:"1 6 8 3 16 6 23 3 23 18 16 21 8 18 1 21 1 6"}),n("line",{x1:"8",y1:"3",x2:"8",y2:"18"}),n("line",{x1:"16",y1:"6",x2:"16",y2:"21"})]})}import{useEffect as Pe,useState as Se}from"react";import{jsx as s,jsxs as d}from"react/jsx-runtime";var we=s("div",{className:"rle-empty",children:"Map unavailable"});function oe({search:e,toolbarEnd:r,mobileAction:t,autoFetch:i=!0,hasMap:o=!0,mapCenter:a,mapZoom:p,className:c}){let f=N(),{Search:w}=U(),{filters:L}=Z(),[h,x]=Se("list"),m=e?{value:String(L[e.filterKey]??""),onChange:b=>{f.applyFilters({[e.filterKey]:b||void 0})},placeholder:e.placeholder}:void 0;return Pe(()=>{i!==!1&&f.applyFilters({})},[f,i]),d("div",{className:c?`rle-app ${c}`:"rle-app",children:[d("div",{className:"rle-filter-bar",children:[d("div",{className:"rle-filter-bar__controls",children:[m&&s("div",{className:"rle-filter-bar__search",children:s(w,{value:m.value,onChange:m.onChange,placeholder:m.placeholder})}),s(q,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),d("div",{className:"rle-filter-bar__end",children:[s("span",{className:"rle-filter-bar__count",children:s(X,{})}),t&&d("button",{type:"button",className:"rle-filter-bar__action",onClick:t.onClick,children:[t.icon,s("span",{children:t.label})]}),r]})]}),d("div",{className:`rle-body ${o?"rle-split":"rle-body--list-only"}`,"data-mobile-view":h,children:[d("div",{className:"rle-list",children:[s(G,{className:"rle-list-grid"}),s(Q,{})]}),o&&s("div",{className:"rle-map",children:s(J,{center:a,zoom:p,fallback:we})})]}),o&&s(ie,{view:h,onViewChange:x})]})}import{useEffect as xe,useRef as Ce,useState as Ie}from"react";import{jsx as V,jsxs as Me}from"react/jsx-runtime";function ne(e){return"provider"in e}function ke(e){let r=e!=null&&!ne(e),t=r?e.apiKey:void 0,i=r?e.mapId:void 0,[o,a]=Ie(()=>!e||ne(e)?{ready:!0,provider:e?.provider}:{ready:!1});return xe(()=>{if(!t)return;let p=!1;return import("./maps/google/index.js").then(({googleProvider:c})=>{p||a({ready:!0,provider:c({apiKey:t,mapId:i})})}),()=>{p=!0}},[t,i]),o}function Fe({onFiltersChange:e}){let r=Ce(e);return r.current=e,j("FiltersChanged",t=>{t.type==="FiltersChanged"&&r.current(t.filters)}),null}function Ft(e){let{datasets:r,filters:t,map:i,components:o,initialFilters:a,onFiltersChange:p,mobileAction:c,search:f,toolbarEnd:w,config:L,autoFetch:h,className:x}=e,{ready:m,provider:b}=ke(i);if(!m)return null;let u=[];for(let le of r)u.push(H(le));t&&u.push($(t)),b&&u.push(W(b)),a&&u.push(O(a)),L&&u.push(D(L));let se=K(...u),ae={...re,...o};return Me(Y,{...se,children:[p&&V(Fe,{onFiltersChange:p}),V(z,{...ae,children:V(oe,{className:x,search:f,toolbarEnd:w,mobileAction:c,autoFetch:h,hasMap:i!=null,mapCenter:i?.center,mapZoom:i?.zoom})})]})}export{j as a,C as b,I as c,k as d,F as e,M as f,E as g,R as h,_ as i,B as j,A as k,re as l,ie as m,oe as n,Ft as o};
@@ -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; }"use client";
2
+ var _chunkEYXV5OMYcjs = require('./chunk-EYXV5OMY.cjs');var _react = require('react');function j(e,r){let t=_chunkEYXV5OMYcjs.s.call(void 0, ),i=_react.useRef.call(void 0, r);i.current=r,_react.useEffect.call(void 0, ()=>t.on(e,o=>i.current(o)),[t,e])}function g(e){return typeof e!="number"?e:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(e)}var _jsxruntime = require('react/jsx-runtime');function ce(e){return e?"rle-card rle-card--selected":"rle-card"}function C({item:e,selected:r,onSelect:t}){let i=_nullishCoalesce(e, () => ({})),o=ce(r),a=_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[i.imageUrl?_jsxruntime.jsx.call(void 0, "img",{src:i.imageUrl,alt:_nullishCoalesce(i.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:[i.title&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-title",children:i.title}),i.subtitle&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-address",children:i.subtitle}),i.badge&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-info",children:_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-info-item",children:i.badge})}),i.price!=null&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-price",children:g(i.price)})]})]});return t?_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:t,"aria-pressed":_nullishCoalesce(r, () => (!1)),className:o,children:a}):_jsxruntime.jsx.call(void 0, "article",{className:o,children:a})}function I(e){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 k({children:e}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-panel",children:e})}function F(e){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((r,t)=>_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%"}})]},t))})}function M({point:e}){let r=_nullishCoalesce(e.entity, () => ({}));return _jsxruntime.jsx.call(void 0, "span",{className:"rle-pin",children:r.price!=null?g(r.price):""})}function E({entity:e,onClose:r}){let t=_nullishCoalesce(e, () => ({}));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:r,"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:[t.title&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-title",children:t.title}),t.subtitle&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-address",children:t.subtitle}),t.price!=null&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-price",children:g(t.price)})]})]})}function R({count:e,total:r}){let t=r!=null&&r!==e?`${e} of ${r} results`:`${e} results`;return _jsxruntime.jsx.call(void 0, "div",{className:"rle-result-header",children:t})}function _({value:e,onChange:r,placeholder:t}){return _jsxruntime.jsx.call(void 0, "input",{type:"search",value:e,placeholder:t,onChange:i=>r(i.target.value),"aria-label":_nullishCoalesce(t, () => ("Search")),className:"rle-input"})}function B({children:e}){return _jsxruntime.jsx.call(void 0, "aside",{className:"rle-sidebar",children:e})}function A({children:e}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-toolbar",children:e})}var re={Card:C,Marker:M,Popup:E,Sidebar:B,FilterPanel:k,Search:_,Empty:I,Loading:F,ResultHeader:R,Toolbar:A};function ie({view:e,onViewChange:r}){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${e==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":e==="list",onClick:()=>r("list"),children:[_jsxruntime.jsx.call(void 0, be,{}),"List"]}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:`rle-viewtoggle__btn${e==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":e==="map",onClick:()=>r("map"),children:[_jsxruntime.jsx.call(void 0, Ne,{}),"Map"]})]})})}function be(){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 Ne(){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 we=_jsxruntime.jsx.call(void 0, "div",{className:"rle-empty",children:"Map unavailable"});function oe({search:e,toolbarEnd:r,mobileAction:t,autoFetch:i=!0,hasMap:o=!0,mapCenter:a,mapZoom:p,className:c}){let f=_chunkEYXV5OMYcjs.s.call(void 0, ),{Search:w}=_chunkEYXV5OMYcjs.q.call(void 0, ),{filters:L}=_chunkEYXV5OMYcjs.u.call(void 0, ),[h,x]=_react.useState.call(void 0, "list"),m=e?{value:String(_nullishCoalesce(L[e.filterKey], () => (""))),onChange:b=>{f.applyFilters({[e.filterKey]:b||void 0})},placeholder:e.placeholder}:void 0;return _react.useEffect.call(void 0, ()=>{i!==!1&&f.applyFilters({})},[f,i]),_jsxruntime.jsxs.call(void 0, "div",{className:c?`rle-app ${c}`:"rle-app",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar__controls",children:[m&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__search",children:_jsxruntime.jsx.call(void 0, w,{value:m.value,onChange:m.onChange,placeholder:m.placeholder})}),_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.v,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0})]}),_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar__end",children:[_jsxruntime.jsx.call(void 0, "span",{className:"rle-filter-bar__count",children:_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.A,{})}),t&&_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:"rle-filter-bar__action",onClick:t.onClick,children:[t.icon,_jsxruntime.jsx.call(void 0, "span",{children:t.label})]}),r]})]}),_jsxruntime.jsxs.call(void 0, "div",{className:`rle-body ${o?"rle-split":"rle-body--list-only"}`,"data-mobile-view":h,children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list",children:[_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.x,{className:"rle-list-grid"}),_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.z,{})]}),o&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-map",children:_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.y,{center:a,zoom:p,fallback:we})})]}),o&&_jsxruntime.jsx.call(void 0, ie,{view:h,onViewChange:x})]})}function ne(e){return"provider"in e}function ke(e){let r=e!=null&&!ne(e),t=r?e.apiKey:void 0,i=r?e.mapId:void 0,[o,a]=_react.useState.call(void 0, ()=>!e||ne(e)?{ready:!0,provider:_optionalChain([e, 'optionalAccess', _2 => _2.provider])}:{ready:!1});return _react.useEffect.call(void 0, ()=>{if(!t)return;let p=!1;return Promise.resolve().then(() => _interopRequireWildcard(require("./maps/google/index.cjs"))).then(({googleProvider:c})=>{p||a({ready:!0,provider:c({apiKey:t,mapId:i})})}),()=>{p=!0}},[t,i]),o}function Fe({onFiltersChange:e}){let r=_react.useRef.call(void 0, e);return r.current=e,j("FiltersChanged",t=>{t.type==="FiltersChanged"&&r.current(t.filters)}),null}function Ft(e){let{datasets:r,filters:t,map:i,components:o,initialFilters:a,onFiltersChange:p,mobileAction:c,search:f,toolbarEnd:w,config:L,autoFetch:h,className:x}=e,{ready:m,provider:b}=ke(i);if(!m)return null;let u=[];for(let le of r)u.push(_chunkEYXV5OMYcjs.k.call(void 0, le));t&&u.push(_chunkEYXV5OMYcjs.l.call(void 0, t)),b&&u.push(_chunkEYXV5OMYcjs.j.call(void 0, b)),a&&u.push(_chunkEYXV5OMYcjs.n.call(void 0, a)),L&&u.push(_chunkEYXV5OMYcjs.i.call(void 0, L));let se=_chunkEYXV5OMYcjs.h.call(void 0, ...u),ae={...re,...o};return _jsxruntime.jsxs.call(void 0, _chunkEYXV5OMYcjs.B,{...se,children:[p&&_jsxruntime.jsx.call(void 0, Fe,{onFiltersChange:p}),_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.p,{...ae,children:_jsxruntime.jsx.call(void 0, oe,{className:x,search:f,toolbarEnd:w,mobileAction:c,autoFetch:h,hasMap:i!=null,mapCenter:_optionalChain([i, 'optionalAccess', _3 => _3.center]),mapZoom:_optionalChain([i, 'optionalAccess', _4 => _4.zoom])})})]})}exports.a = j; exports.b = C; exports.c = I; exports.d = k; exports.e = F; exports.f = M; exports.g = E; exports.h = R; exports.i = _; exports.j = B; exports.k = A; exports.l = re; exports.m = ie; exports.n = oe; exports.o = Ft;
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(); } } var _class;"use client";
2
- var _chunkJNURPGEBcjs = require('./chunk-JNURPGEB.cjs');var _chunkEYXV5OMYcjs = require('./chunk-EYXV5OMY.cjs');var _chunkCHNUE46Kcjs = require('./chunk-CHNUE46K.cjs');var _chunk2VUHLHHXcjs = require('./chunk-2VUHLHHX.cjs');var d=(o=>(o.Paged="paged",o.Infinite="infinite",o))(d||{});var f=(r=>(r.FiltersChanged="FiltersChanged",r.ResultsLoaded="ResultsLoaded",r.PointClicked="PointClicked",r.BoundsChanged="BoundsChanged",r.LayerToggled="LayerToggled",r))(f||{});var u= (_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);var _jsxruntime = require('react/jsx-runtime');function Z({children:e}){let{Toolbar:t}=_chunkEYXV5OMYcjs.q.call(void 0, );return _jsxruntime.jsx.call(void 0, t,{children:e})}var _react = require('react');function tt(){let e=_chunkEYXV5OMYcjs.s.call(void 0, ),t=_chunkEYXV5OMYcjs.t.call(void 0, ),o=_react.useCallback.call(void 0, a=>e.loadPoints(a),[e]),n=_react.useCallback.call(void 0, (a,r)=>e.selectPoint(a,r),[e]);return{bounds:t.bounds,points:t.points,loadPoints:o,selectPoint:n}}function it(e){let t=_chunkEYXV5OMYcjs.s.call(void 0, ),o=_chunkEYXV5OMYcjs.t.call(void 0, ),n=_react.useCallback.call(void 0, ()=>t.toggleLayer(e),[t,e]);return{visible:_nullishCoalesce(o.layers[e], () => (!0)),points:_nullishCoalesce(o.points[e], () => ([])),toggle:n}}exports.BrowserHistoryPort = _chunkCHNUE46Kcjs.a; exports.DatasetRegistry = _chunkEYXV5OMYcjs.c; exports.FilterRegistry = _chunkEYXV5OMYcjs.b; exports.ListingApp = _chunkJNURPGEBcjs.p; exports.ListingComponentsProvider = _chunkEYXV5OMYcjs.p; exports.ListingConfig = _chunkEYXV5OMYcjs.f; exports.ListingEngine = _chunkEYXV5OMYcjs.g; exports.ListingEngineContext = _chunkEYXV5OMYcjs.r; exports.ListingEventType = f; exports.ListingFilters = _chunkEYXV5OMYcjs.v; exports.ListingList = _chunkEYXV5OMYcjs.x; exports.ListingMap = _chunkEYXV5OMYcjs.y; exports.ListingPagination = _chunkEYXV5OMYcjs.z; exports.ListingProvider = _chunkEYXV5OMYcjs.B; exports.ListingResultHeader = _chunkEYXV5OMYcjs.A; exports.ListingStore = _chunkEYXV5OMYcjs.a; exports.ListingToolbar = Z; exports.MemoryHistoryPort = u; exports.PaginationMode = d; exports.TypedEmitter = _chunkEYXV5OMYcjs.d; exports.UrlSyncController = _chunk2VUHLHHXcjs.a; exports.composeListingProviders = _chunkEYXV5OMYcjs.h; exports.listingDefaultConfig = _chunkEYXV5OMYcjs.e; exports.useListing = _chunkEYXV5OMYcjs.s; exports.useListingComponents = _chunkEYXV5OMYcjs.q; exports.useListingEvent = _chunkJNURPGEBcjs.a; exports.useListingFilters = _chunkEYXV5OMYcjs.u; exports.useListingLayer = it; exports.useListingMap = tt; exports.useListingResults = _chunkEYXV5OMYcjs.w; exports.useListingState = _chunkEYXV5OMYcjs.t; exports.withConfig = _chunkEYXV5OMYcjs.i; exports.withDataset = _chunkEYXV5OMYcjs.k; exports.withFilters = _chunkEYXV5OMYcjs.l; exports.withInitialFilters = _chunkEYXV5OMYcjs.n; exports.withMap = _chunkEYXV5OMYcjs.j; exports.withPrimaryDataset = _chunkEYXV5OMYcjs.o; exports.withUrlSync = _chunkEYXV5OMYcjs.m;
2
+ var _chunk5NZBR3MIcjs = require('./chunk-5NZBR3MI.cjs');var _chunkEYXV5OMYcjs = require('./chunk-EYXV5OMY.cjs');var _chunkCHNUE46Kcjs = require('./chunk-CHNUE46K.cjs');var _chunk2VUHLHHXcjs = require('./chunk-2VUHLHHX.cjs');var d=(o=>(o.Paged="paged",o.Infinite="infinite",o))(d||{});var f=(r=>(r.FiltersChanged="FiltersChanged",r.ResultsLoaded="ResultsLoaded",r.PointClicked="PointClicked",r.BoundsChanged="BoundsChanged",r.LayerToggled="LayerToggled",r))(f||{});var u= (_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);var _jsxruntime = require('react/jsx-runtime');function Z({children:e}){let{Toolbar:t}=_chunkEYXV5OMYcjs.q.call(void 0, );return _jsxruntime.jsx.call(void 0, t,{children:e})}var _react = require('react');function tt(){let e=_chunkEYXV5OMYcjs.s.call(void 0, ),t=_chunkEYXV5OMYcjs.t.call(void 0, ),o=_react.useCallback.call(void 0, a=>e.loadPoints(a),[e]),n=_react.useCallback.call(void 0, (a,r)=>e.selectPoint(a,r),[e]);return{bounds:t.bounds,points:t.points,loadPoints:o,selectPoint:n}}function it(e){let t=_chunkEYXV5OMYcjs.s.call(void 0, ),o=_chunkEYXV5OMYcjs.t.call(void 0, ),n=_react.useCallback.call(void 0, ()=>t.toggleLayer(e),[t,e]);return{visible:_nullishCoalesce(o.layers[e], () => (!0)),points:_nullishCoalesce(o.points[e], () => ([])),toggle:n}}exports.BrowserHistoryPort = _chunkCHNUE46Kcjs.a; exports.DatasetRegistry = _chunkEYXV5OMYcjs.c; exports.FilterRegistry = _chunkEYXV5OMYcjs.b; exports.ListingApp = _chunk5NZBR3MIcjs.o; exports.ListingComponentsProvider = _chunkEYXV5OMYcjs.p; exports.ListingConfig = _chunkEYXV5OMYcjs.f; exports.ListingEngine = _chunkEYXV5OMYcjs.g; exports.ListingEngineContext = _chunkEYXV5OMYcjs.r; exports.ListingEventType = f; exports.ListingFilters = _chunkEYXV5OMYcjs.v; exports.ListingList = _chunkEYXV5OMYcjs.x; exports.ListingMap = _chunkEYXV5OMYcjs.y; exports.ListingPagination = _chunkEYXV5OMYcjs.z; exports.ListingProvider = _chunkEYXV5OMYcjs.B; exports.ListingResultHeader = _chunkEYXV5OMYcjs.A; exports.ListingStore = _chunkEYXV5OMYcjs.a; exports.ListingToolbar = Z; exports.MemoryHistoryPort = u; exports.PaginationMode = d; exports.TypedEmitter = _chunkEYXV5OMYcjs.d; exports.UrlSyncController = _chunk2VUHLHHXcjs.a; exports.composeListingProviders = _chunkEYXV5OMYcjs.h; exports.listingDefaultConfig = _chunkEYXV5OMYcjs.e; exports.useListing = _chunkEYXV5OMYcjs.s; exports.useListingComponents = _chunkEYXV5OMYcjs.q; exports.useListingEvent = _chunk5NZBR3MIcjs.a; exports.useListingFilters = _chunkEYXV5OMYcjs.u; exports.useListingLayer = it; exports.useListingMap = tt; exports.useListingResults = _chunkEYXV5OMYcjs.w; exports.useListingState = _chunkEYXV5OMYcjs.t; exports.withConfig = _chunkEYXV5OMYcjs.i; exports.withDataset = _chunkEYXV5OMYcjs.k; exports.withFilters = _chunkEYXV5OMYcjs.l; exports.withInitialFilters = _chunkEYXV5OMYcjs.n; exports.withMap = _chunkEYXV5OMYcjs.j; exports.withPrimaryDataset = _chunkEYXV5OMYcjs.o; exports.withUrlSync = _chunkEYXV5OMYcjs.m;
package/dist/index.d.cts CHANGED
@@ -9,7 +9,7 @@ import { H as HistoryPort, U as UrlSyncController } from './url-sync.controller-
9
9
  export { a as UrlSyncEngine, b as UrlSyncOptions } from './url-sync.controller-CsU_QxoS.cjs';
10
10
  import * as react from 'react';
11
11
  import { ReactNode } from 'react';
12
- export { L as ListingApp, a as ListingAppProps } from './listing-app-D2UB9ru3.cjs';
12
+ export { L as ListingApp, a as ListingAppProps } from './listing-app-DQ1FqQwY.cjs';
13
13
 
14
14
  declare enum ListingEventType {
15
15
  FiltersChanged = "FiltersChanged",
package/dist/index.d.ts CHANGED
@@ -9,7 +9,7 @@ import { H as HistoryPort, U as UrlSyncController } from './url-sync.controller-
9
9
  export { a as UrlSyncEngine, b as UrlSyncOptions } from './url-sync.controller-DX67JivW.js';
10
10
  import * as react from 'react';
11
11
  import { ReactNode } from 'react';
12
- export { L as ListingApp, a as ListingAppProps } from './listing-app-DDKZ6Inn.js';
12
+ export { L as ListingApp, a as ListingAppProps } from './listing-app-Cu-9sydx.js';
13
13
 
14
14
  declare enum ListingEventType {
15
15
  FiltersChanged = "FiltersChanged",
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{a as O,p as m}from"./chunk-HOIUTFFL.js";import{A as N,B as U,a as y,b as P,c as L,d as h,e as b,f as x,g as C,h as I,i as k,j as q,k as v,l as B,m as S,n as A,o as F,p as T,q as p,r as w,s,t as i,u as H,v as z,w as D,x as G,y as J,z as K}from"./chunk-R3FX2V3N.js";import{a as R}from"./chunk-5FBI2WIM.js";import{a as Q}from"./chunk-35KYEBAC.js";var d=(o=>(o.Paged="paged",o.Infinite="infinite",o))(d||{});var f=(r=>(r.FiltersChanged="FiltersChanged",r.ResultsLoaded="ResultsLoaded",r.PointClicked="PointClicked",r.BoundsChanged="BoundsChanged",r.LayerToggled="LayerToggled",r))(f||{});var u=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()}};import{jsx as c}from"react/jsx-runtime";function Z({children:e}){let{Toolbar:t}=p();return c(t,{children:e})}import{useCallback as l}from"react";function tt(){let e=s(),t=i(),o=l(a=>e.loadPoints(a),[e]),n=l((a,r)=>e.selectPoint(a,r),[e]);return{bounds:t.bounds,points:t.points,loadPoints:o,selectPoint:n}}import{useCallback as g}from"react";function it(e){let t=s(),o=i(),n=g(()=>t.toggleLayer(e),[t,e]);return{visible:o.layers[e]??!0,points:o.points[e]??[],toggle:n}}export{R as BrowserHistoryPort,L as DatasetRegistry,P as FilterRegistry,m as ListingApp,T as ListingComponentsProvider,x as ListingConfig,C as ListingEngine,w as ListingEngineContext,f as ListingEventType,z as ListingFilters,G as ListingList,J as ListingMap,K as ListingPagination,U as ListingProvider,N as ListingResultHeader,y as ListingStore,Z as ListingToolbar,u as MemoryHistoryPort,d as PaginationMode,h as TypedEmitter,Q as UrlSyncController,I as composeListingProviders,b as listingDefaultConfig,s as useListing,p as useListingComponents,O as useListingEvent,H as useListingFilters,it as useListingLayer,tt as useListingMap,D as useListingResults,i as useListingState,k as withConfig,v as withDataset,B as withFilters,A as withInitialFilters,q as withMap,F as withPrimaryDataset,S as withUrlSync};
2
+ import{a as O,o as m}from"./chunk-2HQ3HB7P.js";import{A as N,B as U,a as y,b as P,c as L,d as h,e as b,f as x,g as C,h as I,i as k,j as q,k as v,l as B,m as S,n as A,o as F,p as T,q as p,r as w,s,t as i,u as H,v as z,w as D,x as G,y as J,z as K}from"./chunk-R3FX2V3N.js";import{a as R}from"./chunk-5FBI2WIM.js";import{a as Q}from"./chunk-35KYEBAC.js";var d=(o=>(o.Paged="paged",o.Infinite="infinite",o))(d||{});var f=(r=>(r.FiltersChanged="FiltersChanged",r.ResultsLoaded="ResultsLoaded",r.PointClicked="PointClicked",r.BoundsChanged="BoundsChanged",r.LayerToggled="LayerToggled",r))(f||{});var u=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()}};import{jsx as c}from"react/jsx-runtime";function Z({children:e}){let{Toolbar:t}=p();return c(t,{children:e})}import{useCallback as l}from"react";function tt(){let e=s(),t=i(),o=l(a=>e.loadPoints(a),[e]),n=l((a,r)=>e.selectPoint(a,r),[e]);return{bounds:t.bounds,points:t.points,loadPoints:o,selectPoint:n}}import{useCallback as g}from"react";function it(e){let t=s(),o=i(),n=g(()=>t.toggleLayer(e),[t,e]);return{visible:o.layers[e]??!0,points:o.points[e]??[],toggle:n}}export{R as BrowserHistoryPort,L as DatasetRegistry,P as FilterRegistry,m as ListingApp,T as ListingComponentsProvider,x as ListingConfig,C as ListingEngine,w as ListingEngineContext,f as ListingEventType,z as ListingFilters,G as ListingList,J as ListingMap,K as ListingPagination,U as ListingProvider,N as ListingResultHeader,y as ListingStore,Z as ListingToolbar,u as MemoryHistoryPort,d as PaginationMode,h as TypedEmitter,Q as UrlSyncController,I as composeListingProviders,b as listingDefaultConfig,s as useListing,p as useListingComponents,O as useListingEvent,H as useListingFilters,it as useListingLayer,tt as useListingMap,D as useListingResults,i as useListingState,k as withConfig,v as withDataset,B as withFilters,A as withInitialFilters,q as withMap,F as withPrimaryDataset,S as withUrlSync};
@@ -20,7 +20,7 @@ interface IBottomNavProps {
20
20
  * see `styles.css`): a floating **List | Map** segmented toggle
21
21
  * (`.rle-viewtoggle`) that drives which of `StyledListingLayout`'s two
22
22
  * full-area panels is visible. The **Filters** button and the optional caller
23
- * action (e.g. "Save") live in the mobile header (`MobileHeader`) instead, so
23
+ * action (e.g. "Save") live in the sticky filter bar (`.rle-filter-bar`) instead, so
24
24
  * the footer pill carries the view toggle alone. No lucide/icon library
25
25
  * dependency -- every icon here is a small inline SVG, matching the rest of
26
26
  * `/styled`'s zero-extra-dependency policy.
@@ -29,21 +29,21 @@ declare function BottomNav({ view, onViewChange }: IBottomNavProps): react.JSX.E
29
29
 
30
30
  interface IStyledListingLayoutProps {
31
31
  /**
32
- * Optional header search box, LIBRARY-wired (unlike `/shadcn`'s
33
- * consumer-managed `search`): name the `TFilters` field it drives via
34
- * `filterKey`, and the layout reads the current value from the engine's
35
- * filters and writes edits back with `applyFilters({ [filterKey]: value ||
36
- * undefined })`. Rendered in BOTH the desktop filter bar and the mobile
37
- * header. Do NOT also register `filterKey` as a `ListingFilters` control --
38
- * it would then render twice. Omitted entirely when not passed.
32
+ * Optional search box, LIBRARY-wired (unlike `/shadcn`'s consumer-managed
33
+ * `search`): name the `TFilters` field it drives via `filterKey`, and the
34
+ * layout reads the current value from the engine's filters and writes edits
35
+ * back with `applyFilters({ [filterKey]: value || undefined })`. Rendered as
36
+ * the first control in the filter bar. Do NOT also register `filterKey` as a
37
+ * `ListingFilters` control -- it would then render twice. Omitted entirely
38
+ * when not passed.
39
39
  */
40
40
  search?: {
41
41
  filterKey: string;
42
42
  placeholder?: string;
43
43
  };
44
- /** Extra content rendered at the end of the desktop filter bar, alongside `ListingResultHeader` (e.g. a sort control). */
44
+ /** Extra content rendered at the end of the filter bar, alongside `ListingResultHeader` (e.g. a sort control). */
45
45
  toolbarEnd?: ReactNode;
46
- /** Optional bottom-nav action button (e.g. "Add"), forwarded verbatim to `<BottomNav action={...} />`. Omit to render just Filters + the List|Map toggle. */
46
+ /** Optional action button (e.g. "Save") rendered at the end of the filter bar. */
47
47
  mobileAction?: IBottomNavAction;
48
48
  /**
49
49
  * Whether a map is configured. When `false`, the map region is dropped and
@@ -63,40 +63,26 @@ interface IStyledListingLayoutProps {
63
63
  /**
64
64
  * Full, responsive, Tailwind-free listing experience -- the `/styled`
65
65
  * counterpart to `/shadcn`'s `ListingLayout`, built from the same
66
- * structure-only compound components (`~/react`) plus the injected
67
- * `Styled*` slot components, but with a richer mobile experience: a bottom
68
- * nav (`BottomNav`) and a bottom sheet (`BottomSheet`) for filters, instead
69
- * of `/shadcn`'s inline mobile toggle bar. Every class used here is one of
70
- * the `.rle-*` layout classes added to `styles.css` alongside this file --
71
- * no Tailwind, no inline styles, no other stylesheet required.
66
+ * structure-only compound components (`~/react`) plus the injected `Styled*`
67
+ * slot components. Every class used here is one of the `.rle-*` layout classes
68
+ * in `styles.css` -- no Tailwind, no inline styles, no other stylesheet.
72
69
  *
73
70
  * STRUCTURE (`.rle-app`):
74
- * - `.rle-filter-bar` (desktop only, hidden below 768px by CSS): the
75
- * optional `Search` slot, `<ListingFilters>` laid out as a wrapping row
76
- * (`className="rle-filters-row"`, `groupClassName="rle-filter-group"`),
77
- * and a trailing `.rle-filter-bar__end` cluster with `<ListingResultHeader>`
78
- * + `toolbarEnd`.
79
- * - `.rle-body.rle-split`: a CSS grid from 768px up (list column floors at
80
- * 340px, caps at 42%; map takes the rest); below that, a single full-area
81
- * panel with exactly one of `.rle-list`/`.rle-map` visible at a time via
82
- * `data-mobile-view` (see `styles.css`'s mobile media query). Both regions
83
- * stay mounted at ALL times regardless of viewport/toggle state -- only
84
- * their visibility flips -- so neither `ListingList` nor `ListingMap`
85
- * remounts (and re-triggers its own mount effects) on toggle or resize.
86
- * - `<BottomNav>`: mobile-only (CSS-hidden at 768px+). Wired to the same
87
- * `mobileView` state as the CSS toggle, `mobileAction`, and opens the
88
- * filters `<BottomSheet>`.
89
- * - `<BottomSheet title="Filters">`: the SAME `<ListingFilters>` component,
90
- * stacked vertically (`className="rle-filter-stack"`) for the sheet's
91
- * narrower body, plus a footer with "Clear all" (resets every registered
92
- * filter to `undefined` via `engine.filters.list()`'s keys, routed through
93
- * `engine.applyFilters` -- the one bulk mutator, same as `ListingFilters`
94
- * itself uses) and "Show N results" (just closes the sheet -- every filter
95
- * control already applies live via its own `onChange`, so there is nothing
96
- * left to commit).
71
+ * - `.rle-filter-bar` (sticky, ALL breakpoints): a `.rle-filter-bar__controls`
72
+ * cluster with the optional search box + `<ListingFilters hideLabels>` (a
73
+ * wrapping row on desktop; a single horizontally-scrolling row on mobile,
74
+ * dashboard-style, so filters stay inline instead of hiding behind a
75
+ * button), and a pinned `.rle-filter-bar__end` cluster with
76
+ * `<ListingResultHeader>`, the optional action, and `toolbarEnd`.
77
+ * - `.rle-body`: `.rle-split` (list-majority grid + map) when a map is present,
78
+ * else `.rle-body--list-only` (full-width multi-column card grid). On mobile,
79
+ * with a map, exactly one of `.rle-list`/`.rle-map` shows at a time via
80
+ * `data-mobile-view` + the `<BottomNav>` List|Map toggle. Both regions stay
81
+ * mounted regardless of toggle/viewport -- only visibility flips.
82
+ * - `<BottomNav>`: the mobile-only List|Map toggle, rendered only when a map
83
+ * exists (nothing to toggle to otherwise).
97
84
  * - Fetches the first page itself on mount (`engine.applyFilters({})`) by
98
- * default, exactly like `/shadcn`'s `ListingLayout` -- pass `autoFetch={false}`
99
- * to opt out and drive the first fetch yourself.
85
+ * default -- pass `autoFetch={false}` to drive the first fetch yourself.
100
86
  */
101
87
  declare function StyledListingLayout({ search, toolbarEnd, mobileAction, autoFetch, hasMap, mapCenter, mapZoom, className, }: IStyledListingLayoutProps): react.JSX.Element;
102
88
 
@@ -20,7 +20,7 @@ interface IBottomNavProps {
20
20
  * see `styles.css`): a floating **List | Map** segmented toggle
21
21
  * (`.rle-viewtoggle`) that drives which of `StyledListingLayout`'s two
22
22
  * full-area panels is visible. The **Filters** button and the optional caller
23
- * action (e.g. "Save") live in the mobile header (`MobileHeader`) instead, so
23
+ * action (e.g. "Save") live in the sticky filter bar (`.rle-filter-bar`) instead, so
24
24
  * the footer pill carries the view toggle alone. No lucide/icon library
25
25
  * dependency -- every icon here is a small inline SVG, matching the rest of
26
26
  * `/styled`'s zero-extra-dependency policy.
@@ -29,21 +29,21 @@ declare function BottomNav({ view, onViewChange }: IBottomNavProps): react.JSX.E
29
29
 
30
30
  interface IStyledListingLayoutProps {
31
31
  /**
32
- * Optional header search box, LIBRARY-wired (unlike `/shadcn`'s
33
- * consumer-managed `search`): name the `TFilters` field it drives via
34
- * `filterKey`, and the layout reads the current value from the engine's
35
- * filters and writes edits back with `applyFilters({ [filterKey]: value ||
36
- * undefined })`. Rendered in BOTH the desktop filter bar and the mobile
37
- * header. Do NOT also register `filterKey` as a `ListingFilters` control --
38
- * it would then render twice. Omitted entirely when not passed.
32
+ * Optional search box, LIBRARY-wired (unlike `/shadcn`'s consumer-managed
33
+ * `search`): name the `TFilters` field it drives via `filterKey`, and the
34
+ * layout reads the current value from the engine's filters and writes edits
35
+ * back with `applyFilters({ [filterKey]: value || undefined })`. Rendered as
36
+ * the first control in the filter bar. Do NOT also register `filterKey` as a
37
+ * `ListingFilters` control -- it would then render twice. Omitted entirely
38
+ * when not passed.
39
39
  */
40
40
  search?: {
41
41
  filterKey: string;
42
42
  placeholder?: string;
43
43
  };
44
- /** Extra content rendered at the end of the desktop filter bar, alongside `ListingResultHeader` (e.g. a sort control). */
44
+ /** Extra content rendered at the end of the filter bar, alongside `ListingResultHeader` (e.g. a sort control). */
45
45
  toolbarEnd?: ReactNode;
46
- /** Optional bottom-nav action button (e.g. "Add"), forwarded verbatim to `<BottomNav action={...} />`. Omit to render just Filters + the List|Map toggle. */
46
+ /** Optional action button (e.g. "Save") rendered at the end of the filter bar. */
47
47
  mobileAction?: IBottomNavAction;
48
48
  /**
49
49
  * Whether a map is configured. When `false`, the map region is dropped and
@@ -63,40 +63,26 @@ interface IStyledListingLayoutProps {
63
63
  /**
64
64
  * Full, responsive, Tailwind-free listing experience -- the `/styled`
65
65
  * counterpart to `/shadcn`'s `ListingLayout`, built from the same
66
- * structure-only compound components (`~/react`) plus the injected
67
- * `Styled*` slot components, but with a richer mobile experience: a bottom
68
- * nav (`BottomNav`) and a bottom sheet (`BottomSheet`) for filters, instead
69
- * of `/shadcn`'s inline mobile toggle bar. Every class used here is one of
70
- * the `.rle-*` layout classes added to `styles.css` alongside this file --
71
- * no Tailwind, no inline styles, no other stylesheet required.
66
+ * structure-only compound components (`~/react`) plus the injected `Styled*`
67
+ * slot components. Every class used here is one of the `.rle-*` layout classes
68
+ * in `styles.css` -- no Tailwind, no inline styles, no other stylesheet.
72
69
  *
73
70
  * STRUCTURE (`.rle-app`):
74
- * - `.rle-filter-bar` (desktop only, hidden below 768px by CSS): the
75
- * optional `Search` slot, `<ListingFilters>` laid out as a wrapping row
76
- * (`className="rle-filters-row"`, `groupClassName="rle-filter-group"`),
77
- * and a trailing `.rle-filter-bar__end` cluster with `<ListingResultHeader>`
78
- * + `toolbarEnd`.
79
- * - `.rle-body.rle-split`: a CSS grid from 768px up (list column floors at
80
- * 340px, caps at 42%; map takes the rest); below that, a single full-area
81
- * panel with exactly one of `.rle-list`/`.rle-map` visible at a time via
82
- * `data-mobile-view` (see `styles.css`'s mobile media query). Both regions
83
- * stay mounted at ALL times regardless of viewport/toggle state -- only
84
- * their visibility flips -- so neither `ListingList` nor `ListingMap`
85
- * remounts (and re-triggers its own mount effects) on toggle or resize.
86
- * - `<BottomNav>`: mobile-only (CSS-hidden at 768px+). Wired to the same
87
- * `mobileView` state as the CSS toggle, `mobileAction`, and opens the
88
- * filters `<BottomSheet>`.
89
- * - `<BottomSheet title="Filters">`: the SAME `<ListingFilters>` component,
90
- * stacked vertically (`className="rle-filter-stack"`) for the sheet's
91
- * narrower body, plus a footer with "Clear all" (resets every registered
92
- * filter to `undefined` via `engine.filters.list()`'s keys, routed through
93
- * `engine.applyFilters` -- the one bulk mutator, same as `ListingFilters`
94
- * itself uses) and "Show N results" (just closes the sheet -- every filter
95
- * control already applies live via its own `onChange`, so there is nothing
96
- * left to commit).
71
+ * - `.rle-filter-bar` (sticky, ALL breakpoints): a `.rle-filter-bar__controls`
72
+ * cluster with the optional search box + `<ListingFilters hideLabels>` (a
73
+ * wrapping row on desktop; a single horizontally-scrolling row on mobile,
74
+ * dashboard-style, so filters stay inline instead of hiding behind a
75
+ * button), and a pinned `.rle-filter-bar__end` cluster with
76
+ * `<ListingResultHeader>`, the optional action, and `toolbarEnd`.
77
+ * - `.rle-body`: `.rle-split` (list-majority grid + map) when a map is present,
78
+ * else `.rle-body--list-only` (full-width multi-column card grid). On mobile,
79
+ * with a map, exactly one of `.rle-list`/`.rle-map` shows at a time via
80
+ * `data-mobile-view` + the `<BottomNav>` List|Map toggle. Both regions stay
81
+ * mounted regardless of toggle/viewport -- only visibility flips.
82
+ * - `<BottomNav>`: the mobile-only List|Map toggle, rendered only when a map
83
+ * exists (nothing to toggle to otherwise).
97
84
  * - Fetches the first page itself on mount (`engine.applyFilters({})`) by
98
- * default, exactly like `/shadcn`'s `ListingLayout` -- pass `autoFetch={false}`
99
- * to opt out and drive the first fetch yourself.
85
+ * default -- pass `autoFetch={false}` to drive the first fetch yourself.
100
86
  */
101
87
  declare function StyledListingLayout({ search, toolbarEnd, mobileAction, autoFetch, hasMap, mapCenter, mapZoom, className, }: IStyledListingLayoutProps): react.JSX.Element;
102
88
 
@@ -1,2 +1,2 @@
1
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; }"use client";
2
- var _jsapiloader = require('@googlemaps/js-api-loader');var y="DEMO_MAP_ID";function u(r){return r.raw}function v(r,n){if(r.element)return r.element;if(r.iconUrl)return new n.PinElement({glyphSrc:r.iconUrl})}function p(r){for(let n of r)n.map=null}var L="#b3261e",b=40,C=64,w=14;function E(r,n){let s=n.count,o=Math.min(C,b+Math.round(Math.log10(s+1)*w)),e=document.createElement("div");return e.textContent=String(s),e.style.display="flex",e.style.alignItems="center",e.style.justifyContent="center",e.style.width=`${o}px`,e.style.height=`${o}px`,e.style.borderRadius="50%",e.style.backgroundColor=L,e.style.border="2px solid #ffffff",e.style.boxShadow="0 1px 4px rgba(0, 0, 0, 0.4)",e.style.color="#ffffff",e.style.fontFamily="inherit",e.style.fontWeight="700",e.style.fontSize=o>=52?"15px":"13px",new r.AdvancedMarkerElement({position:n.position,content:e})}var f=!1;async function h(r,n,s,o){let e;try{e=await Promise.resolve().then(() => _interopRequireWildcard(require("@googlemaps/markerclusterer")))}catch(a){f||(f=!0,console.warn('[react-listing-engine] "@googlemaps/markerclusterer" is not installed -- rendering plain (unclustered) markers instead. Install "@googlemaps/markerclusterer" to enable clustering.',a));return}if(r.layers.get(n)!==s)return;let t=new e.MarkerClusterer({map:r.map,markers:s,algorithmOptions:{maxZoom:o.maxZoom},renderer:{render:a=>E(r.markerLib,a)}});r.clusterers.set(n,t)}function g(r,n){let s=r.clusterers.get(n);s&&(s.setMap(null),r.clusterers.delete(n))}function R(r){let n=r.getSouthWest(),s=r.getNorthEast();return{west:n.lng(),south:n.lat(),east:s.lng(),north:s.lat()}}function O(r,n,s){if(typeof ResizeObserver>"u")return;let o=!1,e=()=>{let{width:a,height:i}=r.getBoundingClientRect();a===0||i===0||(google.maps.event.trigger(n,"resize"),o||(o=!0,n.setCenter(s)))},t=new ResizeObserver(e);return t.observe(r),typeof requestAnimationFrame<"u"?requestAnimationFrame(e):queueMicrotask(e),t}function P(r){if(!r.apiKey)throw new Error("googleProvider: config.apiKey is required (no hardcoded fallback key is ever used).");let n=!1,s=()=>{n||(_jsapiloader.setOptions.call(void 0, {...r.loaderOptions,key:r.apiKey}),n=!0)};return{async mount(o,e){s();let t=await _jsapiloader.importLibrary.call(void 0, "maps"),a=await _jsapiloader.importLibrary.call(void 0, "marker"),i=_nullishCoalesce(e.center, () => ({lat:0,lng:0})),l=new t.Map(o,{center:i,zoom:_nullishCoalesce(e.zoom, () => (10)),mapId:_nullishCoalesce(r.mapId, () => (y))}),d=O(o,l,i);return{raw:{map:l,markerLib:a,layers:new Map,clusterers:new Map,boundsListeners:new Set,resizeObserver:d}}},renderLayer(o,e){let t=u(o),a=t.layers.get(e.id);a&&(p(a),t.layers.delete(e.id)),g(t,e.id);let i=e.markers.map(d=>{let c=new t.markerLib.AdvancedMarkerElement({map:t.map,position:d.position,content:v(d,t.markerLib),gmpClickable:!!e.onMarkerClick});if(e.onMarkerClick){let M=e.onMarkerClick;c.addListener("click",()=>M(d.id))}return c});t.layers.set(e.id,i),e.clustering&&h(t,e.id,i,e.clustering);let l=!1;return()=>{l||(l=!0,t.layers.get(e.id)===i&&(p(i),t.layers.delete(e.id),g(t,e.id)))}},onBoundsChange(o,e){let t=u(o),a=t.map.addListener("idle",()=>{let l=t.map.getBounds();l&&e(R(l))});t.boundsListeners.add(a);let i=!1;return()=>{i||(i=!0,a.remove(),t.boundsListeners.delete(a))}},fitBounds(o,e){u(o).map.fitBounds(e)},destroy(o){let e=u(o);_optionalChain([e, 'access', _ => _.resizeObserver, 'optionalAccess', _2 => _2.disconnect, 'call', _3 => _3()]);for(let t of e.boundsListeners)t.remove();e.boundsListeners.clear();for(let t of[...e.clusterers.keys()])g(e,t);for(let t of e.layers.values())p(t);e.layers.clear()}}}exports.googleProvider = P;
2
+ var _jsapiloader = require('@googlemaps/js-api-loader');var y="DEMO_MAP_ID";function u(r){return r.raw}function v(r,n){if(r.element)return r.element;if(r.iconUrl)return new n.PinElement({glyphSrc:r.iconUrl}).element}function p(r){for(let n of r)n.map=null}var L="#b3261e",b=40,C=64,w=14;function E(r,n){let s=n.count,o=Math.min(C,b+Math.round(Math.log10(s+1)*w)),e=document.createElement("div");return e.textContent=String(s),e.style.display="flex",e.style.alignItems="center",e.style.justifyContent="center",e.style.width=`${o}px`,e.style.height=`${o}px`,e.style.borderRadius="50%",e.style.backgroundColor=L,e.style.border="2px solid #ffffff",e.style.boxShadow="0 1px 4px rgba(0, 0, 0, 0.4)",e.style.color="#ffffff",e.style.fontFamily="inherit",e.style.fontWeight="700",e.style.fontSize=o>=52?"15px":"13px",new r.AdvancedMarkerElement({position:n.position,content:e})}var f=!1;async function h(r,n,s,o){let e;try{e=await Promise.resolve().then(() => _interopRequireWildcard(require("@googlemaps/markerclusterer")))}catch(a){f||(f=!0,console.warn('[react-listing-engine] "@googlemaps/markerclusterer" is not installed -- rendering plain (unclustered) markers instead. Install "@googlemaps/markerclusterer" to enable clustering.',a));return}if(r.layers.get(n)!==s)return;let t=new e.MarkerClusterer({map:r.map,markers:s,algorithmOptions:{maxZoom:o.maxZoom},renderer:{render:a=>E(r.markerLib,a)}});r.clusterers.set(n,t)}function g(r,n){let s=r.clusterers.get(n);s&&(s.setMap(null),r.clusterers.delete(n))}function R(r){let n=r.getSouthWest(),s=r.getNorthEast();return{west:n.lng(),south:n.lat(),east:s.lng(),north:s.lat()}}function O(r,n,s){if(typeof ResizeObserver>"u")return;let o=!1,e=()=>{let{width:a,height:i}=r.getBoundingClientRect();a===0||i===0||(google.maps.event.trigger(n,"resize"),o||(o=!0,n.setCenter(s)))},t=new ResizeObserver(e);return t.observe(r),typeof requestAnimationFrame<"u"?requestAnimationFrame(e):queueMicrotask(e),t}function P(r){if(!r.apiKey)throw new Error("googleProvider: config.apiKey is required (no hardcoded fallback key is ever used).");let n=!1,s=()=>{n||(_jsapiloader.setOptions.call(void 0, {...r.loaderOptions,key:r.apiKey}),n=!0)};return{async mount(o,e){s();let t=await _jsapiloader.importLibrary.call(void 0, "maps"),a=await _jsapiloader.importLibrary.call(void 0, "marker"),i=_nullishCoalesce(e.center, () => ({lat:0,lng:0})),l=new t.Map(o,{center:i,zoom:_nullishCoalesce(e.zoom, () => (10)),mapId:_nullishCoalesce(r.mapId, () => (y))}),d=O(o,l,i);return{raw:{map:l,markerLib:a,layers:new Map,clusterers:new Map,boundsListeners:new Set,resizeObserver:d}}},renderLayer(o,e){let t=u(o),a=t.layers.get(e.id);a&&(p(a),t.layers.delete(e.id)),g(t,e.id);let i=e.markers.map(d=>{let c=new t.markerLib.AdvancedMarkerElement({map:t.map,position:d.position,content:v(d,t.markerLib),gmpClickable:!!e.onMarkerClick});if(e.onMarkerClick){let M=e.onMarkerClick;c.addListener("click",()=>M(d.id))}return c});t.layers.set(e.id,i),e.clustering&&h(t,e.id,i,e.clustering);let l=!1;return()=>{l||(l=!0,t.layers.get(e.id)===i&&(p(i),t.layers.delete(e.id),g(t,e.id)))}},onBoundsChange(o,e){let t=u(o),a=t.map.addListener("idle",()=>{let l=t.map.getBounds();l&&e(R(l))});t.boundsListeners.add(a);let i=!1;return()=>{i||(i=!0,a.remove(),t.boundsListeners.delete(a))}},fitBounds(o,e){u(o).map.fitBounds(e)},destroy(o){let e=u(o);_optionalChain([e, 'access', _ => _.resizeObserver, 'optionalAccess', _2 => _2.disconnect, 'call', _3 => _3()]);for(let t of e.boundsListeners)t.remove();e.boundsListeners.clear();for(let t of[...e.clusterers.keys()])g(e,t);for(let t of e.layers.values())p(t);e.layers.clear()}}}exports.googleProvider = P;
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{importLibrary as m,setOptions as k}from"@googlemaps/js-api-loader";var y="DEMO_MAP_ID";function u(r){return r.raw}function v(r,n){if(r.element)return r.element;if(r.iconUrl)return new n.PinElement({glyphSrc:r.iconUrl})}function p(r){for(let n of r)n.map=null}var L="#b3261e",b=40,C=64,w=14;function E(r,n){let s=n.count,o=Math.min(C,b+Math.round(Math.log10(s+1)*w)),e=document.createElement("div");return e.textContent=String(s),e.style.display="flex",e.style.alignItems="center",e.style.justifyContent="center",e.style.width=`${o}px`,e.style.height=`${o}px`,e.style.borderRadius="50%",e.style.backgroundColor=L,e.style.border="2px solid #ffffff",e.style.boxShadow="0 1px 4px rgba(0, 0, 0, 0.4)",e.style.color="#ffffff",e.style.fontFamily="inherit",e.style.fontWeight="700",e.style.fontSize=o>=52?"15px":"13px",new r.AdvancedMarkerElement({position:n.position,content:e})}var f=!1;async function h(r,n,s,o){let e;try{e=await import("@googlemaps/markerclusterer")}catch(a){f||(f=!0,console.warn('[react-listing-engine] "@googlemaps/markerclusterer" is not installed -- rendering plain (unclustered) markers instead. Install "@googlemaps/markerclusterer" to enable clustering.',a));return}if(r.layers.get(n)!==s)return;let t=new e.MarkerClusterer({map:r.map,markers:s,algorithmOptions:{maxZoom:o.maxZoom},renderer:{render:a=>E(r.markerLib,a)}});r.clusterers.set(n,t)}function g(r,n){let s=r.clusterers.get(n);s&&(s.setMap(null),r.clusterers.delete(n))}function R(r){let n=r.getSouthWest(),s=r.getNorthEast();return{west:n.lng(),south:n.lat(),east:s.lng(),north:s.lat()}}function O(r,n,s){if(typeof ResizeObserver>"u")return;let o=!1,e=()=>{let{width:a,height:i}=r.getBoundingClientRect();a===0||i===0||(google.maps.event.trigger(n,"resize"),o||(o=!0,n.setCenter(s)))},t=new ResizeObserver(e);return t.observe(r),typeof requestAnimationFrame<"u"?requestAnimationFrame(e):queueMicrotask(e),t}function P(r){if(!r.apiKey)throw new Error("googleProvider: config.apiKey is required (no hardcoded fallback key is ever used).");let n=!1,s=()=>{n||(k({...r.loaderOptions,key:r.apiKey}),n=!0)};return{async mount(o,e){s();let t=await m("maps"),a=await m("marker"),i=e.center??{lat:0,lng:0},l=new t.Map(o,{center:i,zoom:e.zoom??10,mapId:r.mapId??y}),d=O(o,l,i);return{raw:{map:l,markerLib:a,layers:new Map,clusterers:new Map,boundsListeners:new Set,resizeObserver:d}}},renderLayer(o,e){let t=u(o),a=t.layers.get(e.id);a&&(p(a),t.layers.delete(e.id)),g(t,e.id);let i=e.markers.map(d=>{let c=new t.markerLib.AdvancedMarkerElement({map:t.map,position:d.position,content:v(d,t.markerLib),gmpClickable:!!e.onMarkerClick});if(e.onMarkerClick){let M=e.onMarkerClick;c.addListener("click",()=>M(d.id))}return c});t.layers.set(e.id,i),e.clustering&&h(t,e.id,i,e.clustering);let l=!1;return()=>{l||(l=!0,t.layers.get(e.id)===i&&(p(i),t.layers.delete(e.id),g(t,e.id)))}},onBoundsChange(o,e){let t=u(o),a=t.map.addListener("idle",()=>{let l=t.map.getBounds();l&&e(R(l))});t.boundsListeners.add(a);let i=!1;return()=>{i||(i=!0,a.remove(),t.boundsListeners.delete(a))}},fitBounds(o,e){u(o).map.fitBounds(e)},destroy(o){let e=u(o);e.resizeObserver?.disconnect();for(let t of e.boundsListeners)t.remove();e.boundsListeners.clear();for(let t of[...e.clusterers.keys()])g(e,t);for(let t of e.layers.values())p(t);e.layers.clear()}}}export{P as googleProvider};
2
+ import{importLibrary as m,setOptions as k}from"@googlemaps/js-api-loader";var y="DEMO_MAP_ID";function u(r){return r.raw}function v(r,n){if(r.element)return r.element;if(r.iconUrl)return new n.PinElement({glyphSrc:r.iconUrl}).element}function p(r){for(let n of r)n.map=null}var L="#b3261e",b=40,C=64,w=14;function E(r,n){let s=n.count,o=Math.min(C,b+Math.round(Math.log10(s+1)*w)),e=document.createElement("div");return e.textContent=String(s),e.style.display="flex",e.style.alignItems="center",e.style.justifyContent="center",e.style.width=`${o}px`,e.style.height=`${o}px`,e.style.borderRadius="50%",e.style.backgroundColor=L,e.style.border="2px solid #ffffff",e.style.boxShadow="0 1px 4px rgba(0, 0, 0, 0.4)",e.style.color="#ffffff",e.style.fontFamily="inherit",e.style.fontWeight="700",e.style.fontSize=o>=52?"15px":"13px",new r.AdvancedMarkerElement({position:n.position,content:e})}var f=!1;async function h(r,n,s,o){let e;try{e=await import("@googlemaps/markerclusterer")}catch(a){f||(f=!0,console.warn('[react-listing-engine] "@googlemaps/markerclusterer" is not installed -- rendering plain (unclustered) markers instead. Install "@googlemaps/markerclusterer" to enable clustering.',a));return}if(r.layers.get(n)!==s)return;let t=new e.MarkerClusterer({map:r.map,markers:s,algorithmOptions:{maxZoom:o.maxZoom},renderer:{render:a=>E(r.markerLib,a)}});r.clusterers.set(n,t)}function g(r,n){let s=r.clusterers.get(n);s&&(s.setMap(null),r.clusterers.delete(n))}function R(r){let n=r.getSouthWest(),s=r.getNorthEast();return{west:n.lng(),south:n.lat(),east:s.lng(),north:s.lat()}}function O(r,n,s){if(typeof ResizeObserver>"u")return;let o=!1,e=()=>{let{width:a,height:i}=r.getBoundingClientRect();a===0||i===0||(google.maps.event.trigger(n,"resize"),o||(o=!0,n.setCenter(s)))},t=new ResizeObserver(e);return t.observe(r),typeof requestAnimationFrame<"u"?requestAnimationFrame(e):queueMicrotask(e),t}function P(r){if(!r.apiKey)throw new Error("googleProvider: config.apiKey is required (no hardcoded fallback key is ever used).");let n=!1,s=()=>{n||(k({...r.loaderOptions,key:r.apiKey}),n=!0)};return{async mount(o,e){s();let t=await m("maps"),a=await m("marker"),i=e.center??{lat:0,lng:0},l=new t.Map(o,{center:i,zoom:e.zoom??10,mapId:r.mapId??y}),d=O(o,l,i);return{raw:{map:l,markerLib:a,layers:new Map,clusterers:new Map,boundsListeners:new Set,resizeObserver:d}}},renderLayer(o,e){let t=u(o),a=t.layers.get(e.id);a&&(p(a),t.layers.delete(e.id)),g(t,e.id);let i=e.markers.map(d=>{let c=new t.markerLib.AdvancedMarkerElement({map:t.map,position:d.position,content:v(d,t.markerLib),gmpClickable:!!e.onMarkerClick});if(e.onMarkerClick){let M=e.onMarkerClick;c.addListener("click",()=>M(d.id))}return c});t.layers.set(e.id,i),e.clustering&&h(t,e.id,i,e.clustering);let l=!1;return()=>{l||(l=!0,t.layers.get(e.id)===i&&(p(i),t.layers.delete(e.id),g(t,e.id)))}},onBoundsChange(o,e){let t=u(o),a=t.map.addListener("idle",()=>{let l=t.map.getBounds();l&&e(R(l))});t.boundsListeners.add(a);let i=!1;return()=>{i||(i=!0,a.remove(),t.boundsListeners.delete(a))}},fitBounds(o,e){u(o).map.fitBounds(e)},destroy(o){let e=u(o);e.resizeObserver?.disconnect();for(let t of e.boundsListeners)t.remove();e.boundsListeners.clear();for(let t of[...e.clusterers.keys()])g(e,t);for(let t of e.layers.values())p(t);e.layers.clear()}}}export{P as googleProvider};
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});"use client";
2
- var _chunkJNURPGEBcjs = require('../chunk-JNURPGEB.cjs');var _chunkEYXV5OMYcjs = require('../chunk-EYXV5OMY.cjs');var _jsxruntime = require('react/jsx-runtime');function L({children:o}){return _jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.p,{..._chunkJNURPGEBcjs.l,children:o})}exports.BottomNav = _chunkJNURPGEBcjs.m; exports.BottomSheet = _chunkJNURPGEBcjs.n; exports.ListingApp = _chunkJNURPGEBcjs.p; exports.StyledCard = _chunkJNURPGEBcjs.b; exports.StyledComponentsProviderWithDefaults = L; exports.StyledEmpty = _chunkJNURPGEBcjs.c; exports.StyledFilterPanel = _chunkJNURPGEBcjs.d; exports.StyledListingLayout = _chunkJNURPGEBcjs.o; exports.StyledLoading = _chunkJNURPGEBcjs.e; exports.StyledMarker = _chunkJNURPGEBcjs.f; exports.StyledPopup = _chunkJNURPGEBcjs.g; exports.StyledResultHeader = _chunkJNURPGEBcjs.h; exports.StyledSearch = _chunkJNURPGEBcjs.i; exports.StyledSidebar = _chunkJNURPGEBcjs.j; exports.StyledToolbar = _chunkJNURPGEBcjs.k; exports.styledDefaultComponents = _chunkJNURPGEBcjs.l;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
2
+ var _chunk5NZBR3MIcjs = require('../chunk-5NZBR3MI.cjs');var _chunkEYXV5OMYcjs = require('../chunk-EYXV5OMY.cjs');var _jsxruntime = require('react/jsx-runtime');function I({children:r}){return _jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.p,{..._chunk5NZBR3MIcjs.l,children:r})}var _react = require('react');var _reactdom = require('react-dom');function M({open:r,onOpenChange:n,title:i,children:v,footer:a}){let p=_react.useRef.call(void 0, null),[o,m]=_react.useState.call(void 0, !1),[u,c]=_react.useState.call(void 0, !1);return _react.useEffect.call(void 0, ()=>{if(!r){c(!1),m(!1);return}m(!0);let t=requestAnimationFrame(()=>c(!0));return()=>cancelAnimationFrame(t)},[r]),_react.useEffect.call(void 0, ()=>{if(!o)return;let t=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=t}},[o]),_react.useEffect.call(void 0, ()=>{if(!o)return;_optionalChain([p, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.focus, 'call', _4 => _4()]);function t(h){h.key==="Escape"&&n(!1)}return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[o,n]),!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${u?" rle-sheet-backdrop--open":""}`,onClick:()=>n(!1),"aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{ref:p,className:`rle-sheet${u?" 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:()=>n(!1),"aria-label":"Close",children:_jsxruntime.jsx.call(void 0, F,{})})]}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__body",children:v}),a&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__footer",children:a})]})]}),document.body)}function F(){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"})]})}exports.BottomNav = _chunk5NZBR3MIcjs.m; exports.BottomSheet = M; exports.ListingApp = _chunk5NZBR3MIcjs.o; exports.StyledCard = _chunk5NZBR3MIcjs.b; exports.StyledComponentsProviderWithDefaults = I; exports.StyledEmpty = _chunk5NZBR3MIcjs.c; exports.StyledFilterPanel = _chunk5NZBR3MIcjs.d; exports.StyledListingLayout = _chunk5NZBR3MIcjs.n; exports.StyledLoading = _chunk5NZBR3MIcjs.e; exports.StyledMarker = _chunk5NZBR3MIcjs.f; exports.StyledPopup = _chunk5NZBR3MIcjs.g; exports.StyledResultHeader = _chunk5NZBR3MIcjs.h; exports.StyledSearch = _chunk5NZBR3MIcjs.i; exports.StyledSidebar = _chunk5NZBR3MIcjs.j; exports.StyledToolbar = _chunk5NZBR3MIcjs.k; exports.styledDefaultComponents = _chunk5NZBR3MIcjs.l;
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { c as IListingCardProps, e as IListingEmptyProps, f as IListingFilterPanelProps, g as IListingLoadingProps, h as IListingMarkerProps, i as IListingPopupProps, j as IListingResultHeaderProps, k as IListingSearchProps, l as IListingSidebarProps, I as IListingToolbarProps, d as IListingComponents } from '../components-provider-CF0Mo0B8.cjs';
4
- export { B as BottomNav, b as BottomNavView, I as IBottomNavAction, c as IBottomNavProps, d as IStyledListingLayoutProps, L as ListingApp, e as ListingAppMapProp, a as ListingAppProps, S as StyledListingLayout } from '../listing-app-D2UB9ru3.cjs';
4
+ export { B as BottomNav, b as BottomNavView, I as IBottomNavAction, c as IBottomNavProps, d as IStyledListingLayoutProps, L as ListingApp, e as ListingAppMapProp, a as ListingAppProps, S as StyledListingLayout } from '../listing-app-DQ1FqQwY.cjs';
5
5
  import '../entity-adapter.interface-BDgbSxhq.cjs';
6
6
  import '../map-provider.interface-BMnwW3ob.cjs';
7
7
  import '../listing-config-options.interface-ZJYY_ZvR.cjs';
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { c as IListingCardProps, e as IListingEmptyProps, f as IListingFilterPanelProps, g as IListingLoadingProps, h as IListingMarkerProps, i as IListingPopupProps, j as IListingResultHeaderProps, k as IListingSearchProps, l as IListingSidebarProps, I as IListingToolbarProps, d as IListingComponents } from '../components-provider-CjMxkxrP.js';
4
- export { B as BottomNav, b as BottomNavView, I as IBottomNavAction, c as IBottomNavProps, d as IStyledListingLayoutProps, L as ListingApp, e as ListingAppMapProp, a as ListingAppProps, S as StyledListingLayout } from '../listing-app-DDKZ6Inn.js';
4
+ export { B as BottomNav, b as BottomNavView, I as IBottomNavAction, c as IBottomNavProps, d as IStyledListingLayoutProps, L as ListingApp, e as ListingAppMapProp, a as ListingAppProps, S as StyledListingLayout } from '../listing-app-Cu-9sydx.js';
5
5
  import '../entity-adapter.interface-BDgbSxhq.js';
6
6
  import '../map-provider.interface-BxexMT3X.js';
7
7
  import '../listing-config-options.interface-ZJYY_ZvR.js';
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- import{b as r,c as p,d as i,e as d,f as y,g as l,h as n,i as m,j as s,k as a,l as t,m as S,n as f,o as P,p as u}from"../chunk-HOIUTFFL.js";import{p as e}from"../chunk-R3FX2V3N.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};
2
+ import{b as S,c as b,d as N,e as L,f as w,g as P,h as g,i as k,j as _,k as x,l,m as B,n as C,o as R}from"../chunk-2HQ3HB7P.js";import{p as f}from"../chunk-R3FX2V3N.js";import{jsx as A}from"react/jsx-runtime";function I({children:r}){return A(f,{...l,children:r})}import{useEffect as s,useRef as E,useState as y}from"react";import{createPortal as D}from"react-dom";import{Fragment as W,jsx as e,jsxs as d}from"react/jsx-runtime";function M({open:r,onOpenChange:n,title:i,children:v,footer:a}){let p=E(null),[o,m]=y(!1),[u,c]=y(!1);return s(()=>{if(!r){c(!1),m(!1);return}m(!0);let t=requestAnimationFrame(()=>c(!0));return()=>cancelAnimationFrame(t)},[r]),s(()=>{if(!o)return;let t=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=t}},[o]),s(()=>{if(!o)return;p.current?.focus();function t(h){h.key==="Escape"&&n(!1)}return document.addEventListener("keydown",t),()=>document.removeEventListener("keydown",t)},[o,n]),!o||typeof document>"u"?null:D(d(W,{children:[e("div",{className:`rle-sheet-backdrop${u?" rle-sheet-backdrop--open":""}`,onClick:()=>n(!1),"aria-hidden":"true"}),d("div",{ref:p,className:`rle-sheet${u?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":i,tabIndex:-1,children:[e("div",{className:"rle-sheet__handle","aria-hidden":"true"}),d("div",{className:"rle-sheet__header",children:[i&&e("div",{className:"rle-sheet__title",children:i}),e("button",{type:"button",className:"rle-sheet__close",onClick:()=>n(!1),"aria-label":"Close",children:e(F,{})})]}),e("div",{className:"rle-sheet__body",children:v}),a&&e("div",{className:"rle-sheet__footer",children:a})]})]}),document.body)}function F(){return d("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[e("path",{d:"M18 6 6 18"}),e("path",{d:"m6 6 12 12"})]})}export{B as BottomNav,M as BottomSheet,R as ListingApp,S as StyledCard,I as StyledComponentsProviderWithDefaults,b as StyledEmpty,N as StyledFilterPanel,C as StyledListingLayout,L as StyledLoading,w as StyledMarker,P as StyledPopup,g as StyledResultHeader,k as StyledSearch,_ as StyledSidebar,x as StyledToolbar,l as styledDefaultComponents};
package/dist/styles.css CHANGED
@@ -650,7 +650,6 @@
650
650
  top: 0;
651
651
  z-index: 10;
652
652
  display: flex;
653
- flex-wrap: wrap;
654
653
  align-items: center;
655
654
  gap: var(--rle-space);
656
655
  padding: var(--rle-space);
@@ -658,86 +657,81 @@
658
657
  border-bottom: 1px solid var(--rle-border);
659
658
  }
660
659
 
661
- /* Bounded so the search sits inline with the filters on one row instead of
662
- taking a full row of its own (the `.rle-input` inside is width:100%). */
663
- .rle-filter-bar__search {
664
- flex: 1 1 200px;
665
- min-width: 180px;
666
- max-width: 340px;
667
- }
668
-
669
- .rle-filter-bar__end {
660
+ /* Search + filter controls. Wraps to multiple rows on desktop; on mobile it's
661
+ a single horizontally-scrolling row (dashboard filter-bar style), so the
662
+ filters stay inline instead of collapsing behind a button. */
663
+ .rle-filter-bar__controls {
670
664
  display: flex;
665
+ flex: 1 1 auto;
671
666
  align-items: center;
672
667
  gap: var(--rle-space);
673
- margin-left: auto;
668
+ min-width: 0;
669
+ }
670
+
671
+ @media (min-width: 768px) {
672
+ .rle-filter-bar__controls {
673
+ flex-wrap: wrap;
674
+ }
674
675
  }
675
676
 
676
677
  @media (max-width: 767px) {
678
+ /* The whole bar is one horizontally-scrolling row (dashboard-style): search
679
+ + filter pills + action all scroll inline; the result count is dropped to
680
+ keep room for the filters. A soft mask fades the scroll edges. */
677
681
  .rle-filter-bar {
678
- display: none;
682
+ flex-wrap: nowrap;
683
+ overflow-x: auto;
684
+ scrollbar-width: none;
685
+ -webkit-overflow-scrolling: touch;
686
+ -webkit-mask-image: linear-gradient(to right, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
687
+ mask-image: linear-gradient(to right, transparent 0, #000 14px, #000 calc(100% - 14px), transparent 100%);
679
688
  }
680
- }
681
689
 
682
- /* `<ListingFilters>`'s own `className`/`groupClassName` hooks (see that
683
- component's doc comment in `~/react`) -- a horizontal, wrapping row for the
684
- desktop filter bar, a vertical stack for the mobile sheet body, and a
685
- shrinkable wrapper for each individual filter group in either layout. */
686
- .rle-filters-row {
687
- display: flex;
688
- flex-wrap: wrap;
689
- align-items: center;
690
- gap: var(--rle-space);
691
- }
690
+ .rle-filter-bar::-webkit-scrollbar {
691
+ display: none;
692
+ }
692
693
 
693
- .rle-filter-stack {
694
- display: flex;
695
- flex-direction: column;
696
- gap: var(--rle-space);
697
- }
694
+ .rle-filter-bar__controls {
695
+ flex: 0 0 auto;
696
+ }
698
697
 
699
- .rle-filter-group {
700
- min-width: 0;
698
+ .rle-filter-bar__count {
699
+ display: none;
700
+ }
701
701
  }
702
702
 
703
- /* -----------------------------------------------------------------------
704
- * Mobile header -- shown below 768px (hidden at 768px+), the compact
705
- * counterpart to the desktop `.rle-filter-bar`: the search input (grows to
706
- * fill), a Filters button that opens the bottom sheet, and an optional
707
- * trailing action (e.g. Save). The List|Map toggle lives in the floating
708
- * footer (`.rle-bottom-nav`) instead.
709
- * --------------------------------------------------------------------- */
710
-
711
- .rle-mobile-header {
712
- display: none;
703
+ /* Bounded so the search sits inline with the filters (the `.rle-input` inside
704
+ is width:100%). On mobile it's a fixed width that scrolls with the row. */
705
+ .rle-filter-bar__search {
706
+ flex: 1 1 200px;
707
+ min-width: 180px;
708
+ max-width: 340px;
713
709
  }
714
710
 
715
711
  @media (max-width: 767px) {
716
- .rle-mobile-header {
717
- position: sticky;
718
- top: 0;
719
- z-index: 10;
720
- display: flex;
721
- align-items: center;
722
- gap: 8px;
723
- padding: var(--rle-space);
724
- background: var(--rle-surface);
725
- border-bottom: 1px solid var(--rle-border);
712
+ .rle-filter-bar__search {
713
+ flex: 0 0 auto;
714
+ width: 180px;
715
+ min-width: 0;
726
716
  }
727
717
  }
728
718
 
729
- .rle-mobile-header__search {
730
- flex: 1;
731
- min-width: 0;
719
+ /* Pinned trailing cluster (result count + optional action) -- stays put while
720
+ `.rle-filter-bar__controls` scrolls on mobile. */
721
+ .rle-filter-bar__end {
722
+ display: flex;
723
+ flex-shrink: 0;
724
+ align-items: center;
725
+ gap: var(--rle-space);
732
726
  }
733
727
 
734
- .rle-mobile-header__btn {
728
+ .rle-filter-bar__action {
735
729
  display: inline-flex;
736
730
  flex-shrink: 0;
737
731
  align-items: center;
738
732
  justify-content: center;
739
733
  gap: 6px;
740
- height: 40px;
734
+ height: 36px;
741
735
  padding: 0 12px;
742
736
  background: var(--rle-surface);
743
737
  border: 1px solid var(--rle-border);
@@ -752,24 +746,51 @@
752
746
  border-color 150ms ease;
753
747
  }
754
748
 
755
- .rle-mobile-header__btn svg {
756
- width: 18px;
757
- height: 18px;
749
+ .rle-filter-bar__action svg {
750
+ width: 16px;
751
+ height: 16px;
758
752
  }
759
753
 
760
- .rle-mobile-header__btn:hover {
754
+ .rle-filter-bar__action:hover {
761
755
  background: var(--rle-muted-bg);
762
756
  }
763
757
 
764
- .rle-mobile-header__btn:focus-visible {
758
+ .rle-filter-bar__action:focus-visible {
765
759
  outline: none;
766
760
  box-shadow: 0 0 0 3px var(--rle-ring);
767
761
  }
768
762
 
769
- .rle-mobile-header__btn--icon {
770
- width: 40px;
771
- padding: 0;
772
- color: var(--rle-muted);
763
+ /* `<ListingFilters>`'s own `className`/`groupClassName` hooks (see that
764
+ component's doc comment in `~/react`) -- a horizontal, wrapping row for the
765
+ desktop filter bar, a vertical stack for the mobile sheet body, and a
766
+ shrinkable wrapper for each individual filter group in either layout. */
767
+ .rle-filters-row {
768
+ display: flex;
769
+ flex-wrap: wrap;
770
+ align-items: center;
771
+ gap: var(--rle-space);
772
+ }
773
+
774
+ .rle-filter-stack {
775
+ display: flex;
776
+ flex-direction: column;
777
+ gap: var(--rle-space);
778
+ }
779
+
780
+ .rle-filter-group {
781
+ min-width: 0;
782
+ }
783
+
784
+ /* Mobile: the filter row is one inline, non-wrapping line inside the scrolling
785
+ `.rle-filter-bar__controls`, and each group keeps its width (scrolls). */
786
+ @media (max-width: 767px) {
787
+ .rle-filters-row {
788
+ flex-wrap: nowrap;
789
+ }
790
+
791
+ .rle-filter-group {
792
+ flex-shrink: 0;
793
+ }
773
794
  }
774
795
 
775
796
  /* -----------------------------------------------------------------------
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-listing-engine",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "license": "MIT",
5
5
  "description": "Headless, composable listing engine for React: filterable list + Google-Maps multi-layer map, with pluggable data adapters, a filter/dataset registry, injectable components, and a shadcn-compatible styled adapter.",
6
6
  "funding": [
@@ -1,2 +0,0 @@
1
- "use client";
2
- import{A as se,B as le,h as G,i as J,j as Q,k as X,l as Y,n as j,p as ee,q as C,s as x,u as te,v as T,w as re,x as ie,y as oe,z as ne}from"./chunk-R3FX2V3N.js";import{useEffect as we,useRef as Pe}from"react";function ae(e,r){let t=x(),i=Pe(r);i.current=r,we(()=>t.on(e,n=>i.current(n)),[t,e])}function b(e){return typeof e!="number"?e:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(e)}import{Fragment as xe,jsx as u,jsxs as de}from"react/jsx-runtime";function Ce(e){return e?"rle-card rle-card--selected":"rle-card"}function B({item:e,selected:r,onSelect:t}){let i=e??{},n=Ce(r),a=de(xe,{children:[i.imageUrl?u("img",{src:i.imageUrl,alt:i.title??"",className:"rle-card-media"}):u("div",{className:"rle-card-media rle-card-media--placeholder","aria-hidden":"true"}),de("div",{className:"rle-card-body",children:[i.title&&u("span",{className:"rle-card-title",children:i.title}),i.subtitle&&u("span",{className:"rle-card-address",children:i.subtitle}),i.badge&&u("div",{className:"rle-card-info",children:u("span",{className:"rle-card-info-item",children:i.badge})}),i.price!=null&&u("span",{className:"rle-card-price",children:b(i.price)})]})]});return t?u("button",{type:"button",onClick:t,"aria-pressed":r??!1,className:n,children:a}):u("article",{className:n,children:a})}import{jsx as k,jsxs as pe}from"react/jsx-runtime";function A(e){return pe("div",{role:"status",className:"rle-empty",children:[pe("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:[k("circle",{cx:"11",cy:"11",r:"7"}),k("path",{d:"m21 21-4.3-4.3"})]}),k("p",{className:"rle-empty-title",children:"No results"}),k("p",{className:"rle-empty-hint",children:"Try adjusting your filters or search terms."})]})}import{jsx as ke}from"react/jsx-runtime";function V({children:e}){return ke("div",{className:"rle-filter-panel",children:e})}import{jsx as I,jsxs as Ie}from"react/jsx-runtime";function K(e){return I("div",{className:"rle-loading",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((r,t)=>Ie("div",{className:"rle-loading-item",children:[I("div",{className:"rle-skeleton",style:{aspectRatio:"4 / 3",width:"100%"}}),I("div",{className:"rle-skeleton",style:{height:16,width:"65%"}}),I("div",{className:"rle-skeleton",style:{height:12,width:"35%"}})]},t))})}import{jsx as Fe}from"react/jsx-runtime";function H({point:e}){let r=e.entity??{};return Fe("span",{className:"rle-pin",children:r.price!=null?b(r.price):""})}import{jsx as L,jsxs as D}from"react/jsx-runtime";function O({entity:e,onClose:r}){let t=e??{};return D("div",{className:"rle-popup",role:"group","aria-label":"Location details",children:[L("button",{type:"button",onClick:r,"aria-label":"Close",className:"rle-popup-close",children:D("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:[L("path",{d:"M18 6 6 18"}),L("path",{d:"m6 6 12 12"})]})}),D("div",{children:[t.title&&L("div",{className:"rle-card-title",children:t.title}),t.subtitle&&L("div",{className:"rle-card-address",children:t.subtitle}),t.price!=null&&L("div",{className:"rle-card-price",children:b(t.price)})]})]})}import{jsx as Me}from"react/jsx-runtime";function W({count:e,total:r}){let t=r!=null&&r!==e?`${e} of ${r} results`:`${e} results`;return Me("div",{className:"rle-result-header",children:t})}import{jsx as _e}from"react/jsx-runtime";function $({value:e,onChange:r,placeholder:t}){return _e("input",{type:"search",value:e,placeholder:t,onChange:i=>r(i.target.value),"aria-label":t??"Search",className:"rle-input"})}import{jsx as Ee}from"react/jsx-runtime";function z({children:e}){return Ee("aside",{className:"rle-sidebar",children:e})}import{jsx as Re}from"react/jsx-runtime";function U({children:e}){return Re("div",{className:"rle-toolbar",children:e})}var ce={Card:B,Marker:H,Popup:O,Sidebar:z,FilterPanel:V,Search:$,Empty:A,Loading:K,ResultHeader:W,Toolbar:U};import{jsx as o,jsxs as y}from"react/jsx-runtime";function me({view:e,onViewChange:r}){return o("nav",{className:"rle-bottom-nav","aria-label":"Listing navigation",children:y("div",{className:"rle-viewtoggle",role:"group","aria-label":"View",children:[y("button",{type:"button",className:`rle-viewtoggle__btn${e==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":e==="list",onClick:()=>r("list"),children:[o(Te,{}),"List"]}),y("button",{type:"button",className:`rle-viewtoggle__btn${e==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":e==="map",onClick:()=>r("map"),children:[o(Be,{}),"Map"]})]})})}function ue(){return y("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[o("line",{x1:"4",y1:"6",x2:"20",y2:"6"}),o("circle",{cx:"9",cy:"6",r:"2",fill:"currentColor",stroke:"none"}),o("line",{x1:"4",y1:"12",x2:"20",y2:"12"}),o("circle",{cx:"15",cy:"12",r:"2",fill:"currentColor",stroke:"none"}),o("line",{x1:"4",y1:"18",x2:"20",y2:"18"}),o("circle",{cx:"11",cy:"18",r:"2",fill:"currentColor",stroke:"none"})]})}function Te(){return y("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[o("line",{x1:"8",y1:"6",x2:"20",y2:"6"}),o("line",{x1:"8",y1:"12",x2:"20",y2:"12"}),o("line",{x1:"8",y1:"18",x2:"20",y2:"18"}),o("line",{x1:"4",y1:"6",x2:"4.01",y2:"6"}),o("line",{x1:"4",y1:"12",x2:"4.01",y2:"12"}),o("line",{x1:"4",y1:"18",x2:"4.01",y2:"18"})]})}function Be(){return y("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[o("polygon",{points:"1 6 8 3 16 6 23 3 23 18 16 21 8 18 1 21 1 6"}),o("line",{x1:"8",y1:"3",x2:"8",y2:"18"}),o("line",{x1:"16",y1:"6",x2:"16",y2:"21"})]})}function ge(){return y("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:[o("line",{x1:"12",y1:"5",x2:"12",y2:"19"}),o("line",{x1:"5",y1:"12",x2:"19",y2:"12"})]})}import{useEffect as Z,useRef as Ae,useState as fe}from"react";import{createPortal as Ve}from"react-dom";import{Fragment as He,jsx as g,jsxs as F}from"react/jsx-runtime";function ye({open:e,onOpenChange:r,title:t,children:i,footer:n}){let a=Ae(null),[l,m]=fe(!1),[p,h]=fe(!1);return Z(()=>{if(!e){h(!1),m(!1);return}m(!0);let d=requestAnimationFrame(()=>h(!0));return()=>cancelAnimationFrame(d)},[e]),Z(()=>{if(!l)return;let d=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=d}},[l]),Z(()=>{if(!l)return;a.current?.focus();function d(S){S.key==="Escape"&&r(!1)}return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[l,r]),!l||typeof document>"u"?null:Ve(F(He,{children:[g("div",{className:`rle-sheet-backdrop${p?" rle-sheet-backdrop--open":""}`,onClick:()=>r(!1),"aria-hidden":"true"}),F("div",{ref:a,className:`rle-sheet${p?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":t,tabIndex:-1,children:[g("div",{className:"rle-sheet__handle","aria-hidden":"true"}),F("div",{className:"rle-sheet__header",children:[t&&g("div",{className:"rle-sheet__title",children:t}),g("button",{type:"button",className:"rle-sheet__close",onClick:()=>r(!1),"aria-label":"Close",children:g(Ke,{})})]}),g("div",{className:"rle-sheet__body",children:i}),n&&g("div",{className:"rle-sheet__footer",children:n})]})]}),document.body)}function Ke(){return F("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",width:"16",height:"16","aria-hidden":"true",children:[g("path",{d:"M18 6 6 18"}),g("path",{d:"m6 6 12 12"})]})}import{useEffect as De,useState as be}from"react";import{jsx as N,jsxs as ve}from"react/jsx-runtime";function he({search:e,onFiltersClick:r,action:t}){let{Search:i}=C();return ve("header",{className:"rle-mobile-header",children:[e&&N("div",{className:"rle-mobile-header__search",children:N(i,{value:e.value,onChange:e.onChange,placeholder:e.placeholder})}),ve("button",{type:"button",className:"rle-mobile-header__btn",onClick:r,children:[N(ue,{}),N("span",{children:"Filters"})]}),t&&N("button",{type:"button",className:"rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:t.onClick,"aria-label":t.label,children:t.icon??N(ge,{})})]})}import{Fragment as We,jsx as s,jsxs as v}from"react/jsx-runtime";var Oe=s("div",{className:"rle-empty",children:"Map unavailable"});function Le({search:e,toolbarEnd:r,mobileAction:t,autoFetch:i=!0,hasMap:n=!0,mapCenter:a,mapZoom:l,className:m}){let p=x(),{Search:h}=C(),d=re(),{filters:S}=te(),[w,M]=be("list"),[P,c]=be(!1),f=e?{value:String(S[e.filterKey]??""),onChange:R=>{p.applyFilters({[e.filterKey]:R||void 0})},placeholder:e.placeholder}:void 0;De(()=>{i!==!1&&p.applyFilters({})},[p,i]);let _=()=>{let R=Object.fromEntries(p.filters.list().map(Se=>[Se.key,void 0]));p.applyFilters(R)},E=d.total??d.items.length;return v("div",{className:m?`rle-app ${m}`:"rle-app",children:[v("div",{className:"rle-filter-bar",children:[f&&s("div",{className:"rle-filter-bar__search",children:s(h,{value:f.value,onChange:f.onChange,placeholder:f.placeholder})}),s(T,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0}),v("div",{className:"rle-filter-bar__end",children:[s(se,{}),r]})]}),s(he,{search:f,onFiltersClick:()=>c(!0),action:t}),v("div",{className:`rle-body ${n?"rle-split":"rle-body--list-only"}`,"data-mobile-view":w,children:[v("div",{className:"rle-list",children:[s(ie,{className:"rle-list-grid"}),s(ne,{})]}),n&&s("div",{className:"rle-map",children:s(oe,{center:a,zoom:l,fallback:Oe})})]}),n&&s(me,{view:w,onViewChange:M}),s(ye,{title:"Filters",open:P,onOpenChange:c,footer:v(We,{children:[s("button",{type:"button",className:"rle-btn rle-btn--ghost",onClick:_,children:"Clear all"}),v("button",{type:"button",className:"rle-btn rle-btn--primary",onClick:()=>c(!1),children:["Show ",E," results"]})]}),children:s(T,{className:"rle-filter-stack",groupClassName:"rle-filter-group"})})]})}import{useEffect as $e,useRef as ze,useState as Ue}from"react";import{jsx as q,jsxs as Ge}from"react/jsx-runtime";function Ne(e){return"provider"in e}function Ze(e){let r=e!=null&&!Ne(e),t=r?e.apiKey:void 0,i=r?e.mapId:void 0,[n,a]=Ue(()=>!e||Ne(e)?{ready:!0,provider:e?.provider}:{ready:!1});return $e(()=>{if(!t)return;let l=!1;return import("./maps/google/index.js").then(({googleProvider:m})=>{l||a({ready:!0,provider:m({apiKey:t,mapId:i})})}),()=>{l=!0}},[t,i]),n}function qe({onFiltersChange:e}){let r=ze(e);return r.current=e,ae("FiltersChanged",t=>{t.type==="FiltersChanged"&&r.current(t.filters)}),null}function ir(e){let{datasets:r,filters:t,map:i,components:n,initialFilters:a,onFiltersChange:l,mobileAction:m,search:p,toolbarEnd:h,config:d,autoFetch:S,className:w}=e,{ready:M,provider:P}=Ze(i);if(!M)return null;let c=[];for(let E of r)c.push(X(E));t&&c.push(Y(t)),P&&c.push(Q(P)),a&&c.push(j(a)),d&&c.push(J(d));let f=G(...c),_={...ce,...n};return Ge(le,{...f,children:[l&&q(qe,{onFiltersChange:l}),q(ee,{..._,children:q(Le,{className:w,search:p,toolbarEnd:h,mobileAction:m,autoFetch:S,hasMap:i!=null,mapCenter:i?.center,mapZoom:i?.zoom})})]})}export{ae as a,B as b,A as c,V as d,K as e,H as f,O as g,W as h,$ as i,z as j,U as k,ce as l,me as m,ye as n,Le as o,ir as p};
@@ -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; }"use client";
2
- var _chunkEYXV5OMYcjs = require('./chunk-EYXV5OMY.cjs');var _react = require('react');function ae(e,r){let t=_chunkEYXV5OMYcjs.s.call(void 0, ),i=_react.useRef.call(void 0, r);i.current=r,_react.useEffect.call(void 0, ()=>t.on(e,n=>i.current(n)),[t,e])}function b(e){return typeof e!="number"?e:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(e)}var _jsxruntime = require('react/jsx-runtime');function Ce(e){return e?"rle-card rle-card--selected":"rle-card"}function B({item:e,selected:r,onSelect:t}){let i=_nullishCoalesce(e, () => ({})),n=Ce(r),a=_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[i.imageUrl?_jsxruntime.jsx.call(void 0, "img",{src:i.imageUrl,alt:_nullishCoalesce(i.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:[i.title&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-title",children:i.title}),i.subtitle&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-address",children:i.subtitle}),i.badge&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-info",children:_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-info-item",children:i.badge})}),i.price!=null&&_jsxruntime.jsx.call(void 0, "span",{className:"rle-card-price",children:b(i.price)})]})]});return t?_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:t,"aria-pressed":_nullishCoalesce(r, () => (!1)),className:n,children:a}):_jsxruntime.jsx.call(void 0, "article",{className:n,children:a})}function A(e){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 V({children:e}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-panel",children:e})}function K(e){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((r,t)=>_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%"}})]},t))})}function H({point:e}){let r=_nullishCoalesce(e.entity, () => ({}));return _jsxruntime.jsx.call(void 0, "span",{className:"rle-pin",children:r.price!=null?b(r.price):""})}function O({entity:e,onClose:r}){let t=_nullishCoalesce(e, () => ({}));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:r,"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:[t.title&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-title",children:t.title}),t.subtitle&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-address",children:t.subtitle}),t.price!=null&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-card-price",children:b(t.price)})]})]})}function W({count:e,total:r}){let t=r!=null&&r!==e?`${e} of ${r} results`:`${e} results`;return _jsxruntime.jsx.call(void 0, "div",{className:"rle-result-header",children:t})}function $({value:e,onChange:r,placeholder:t}){return _jsxruntime.jsx.call(void 0, "input",{type:"search",value:e,placeholder:t,onChange:i=>r(i.target.value),"aria-label":_nullishCoalesce(t, () => ("Search")),className:"rle-input"})}function z({children:e}){return _jsxruntime.jsx.call(void 0, "aside",{className:"rle-sidebar",children:e})}function U({children:e}){return _jsxruntime.jsx.call(void 0, "div",{className:"rle-toolbar",children:e})}var ce={Card:B,Marker:H,Popup:O,Sidebar:z,FilterPanel:V,Search:$,Empty:A,Loading:K,ResultHeader:W,Toolbar:U};function me({view:e,onViewChange:r}){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${e==="list"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":e==="list",onClick:()=>r("list"),children:[_jsxruntime.jsx.call(void 0, Te,{}),"List"]}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:`rle-viewtoggle__btn${e==="map"?" rle-viewtoggle__btn--active":""}`,"aria-pressed":e==="map",onClick:()=>r("map"),children:[_jsxruntime.jsx.call(void 0, Be,{}),"Map"]})]})})}function ue(){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 Te(){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 Be(){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 ge(){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 ye({open:e,onOpenChange:r,title:t,children:i,footer:n}){let a=_react.useRef.call(void 0, null),[l,m]=_react.useState.call(void 0, !1),[p,h]=_react.useState.call(void 0, !1);return _react.useEffect.call(void 0, ()=>{if(!e){h(!1),m(!1);return}m(!0);let d=requestAnimationFrame(()=>h(!0));return()=>cancelAnimationFrame(d)},[e]),_react.useEffect.call(void 0, ()=>{if(!l)return;let d=document.body.style.overflow;return document.body.style.overflow="hidden",()=>{document.body.style.overflow=d}},[l]),_react.useEffect.call(void 0, ()=>{if(!l)return;_optionalChain([a, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.focus, 'call', _4 => _4()]);function d(S){S.key==="Escape"&&r(!1)}return document.addEventListener("keydown",d),()=>document.removeEventListener("keydown",d)},[l,r]),!l||typeof document>"u"?null:_reactdom.createPortal.call(void 0, _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[_jsxruntime.jsx.call(void 0, "div",{className:`rle-sheet-backdrop${p?" rle-sheet-backdrop--open":""}`,onClick:()=>r(!1),"aria-hidden":"true"}),_jsxruntime.jsxs.call(void 0, "div",{ref:a,className:`rle-sheet${p?" rle-sheet--open":""}`,role:"dialog","aria-modal":"true","aria-label":t,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:[t&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__title",children:t}),_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-sheet__close",onClick:()=>r(!1),"aria-label":"Close",children:_jsxruntime.jsx.call(void 0, Ke,{})})]}),_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__body",children:i}),n&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-sheet__footer",children:n})]})]}),document.body)}function Ke(){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 he({search:e,onFiltersClick:r,action:t}){let{Search:i}=_chunkEYXV5OMYcjs.q.call(void 0, );return _jsxruntime.jsxs.call(void 0, "header",{className:"rle-mobile-header",children:[e&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-mobile-header__search",children:_jsxruntime.jsx.call(void 0, i,{value:e.value,onChange:e.onChange,placeholder:e.placeholder})}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:"rle-mobile-header__btn",onClick:r,children:[_jsxruntime.jsx.call(void 0, ue,{}),_jsxruntime.jsx.call(void 0, "span",{children:"Filters"})]}),t&&_jsxruntime.jsx.call(void 0, "button",{type:"button",className:"rle-mobile-header__btn rle-mobile-header__btn--icon",onClick:t.onClick,"aria-label":t.label,children:_nullishCoalesce(t.icon, () => (_jsxruntime.jsx.call(void 0, ge,{})))})]})}var Oe=_jsxruntime.jsx.call(void 0, "div",{className:"rle-empty",children:"Map unavailable"});function Le({search:e,toolbarEnd:r,mobileAction:t,autoFetch:i=!0,hasMap:n=!0,mapCenter:a,mapZoom:l,className:m}){let p=_chunkEYXV5OMYcjs.s.call(void 0, ),{Search:h}=_chunkEYXV5OMYcjs.q.call(void 0, ),d=_chunkEYXV5OMYcjs.w.call(void 0, ),{filters:S}=_chunkEYXV5OMYcjs.u.call(void 0, ),[w,M]=_react.useState.call(void 0, "list"),[P,c]=_react.useState.call(void 0, !1),f=e?{value:String(_nullishCoalesce(S[e.filterKey], () => (""))),onChange:R=>{p.applyFilters({[e.filterKey]:R||void 0})},placeholder:e.placeholder}:void 0;_react.useEffect.call(void 0, ()=>{i!==!1&&p.applyFilters({})},[p,i]);let _=()=>{let R=Object.fromEntries(p.filters.list().map(Se=>[Se.key,void 0]));p.applyFilters(R)},E=_nullishCoalesce(d.total, () => (d.items.length));return _jsxruntime.jsxs.call(void 0, "div",{className:m?`rle-app ${m}`:"rle-app",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar",children:[f&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-filter-bar__search",children:_jsxruntime.jsx.call(void 0, h,{value:f.value,onChange:f.onChange,placeholder:f.placeholder})}),_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.v,{className:"rle-filters-row",groupClassName:"rle-filter-group",hideLabels:!0}),_jsxruntime.jsxs.call(void 0, "div",{className:"rle-filter-bar__end",children:[_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.A,{}),r]})]}),_jsxruntime.jsx.call(void 0, he,{search:f,onFiltersClick:()=>c(!0),action:t}),_jsxruntime.jsxs.call(void 0, "div",{className:`rle-body ${n?"rle-split":"rle-body--list-only"}`,"data-mobile-view":w,children:[_jsxruntime.jsxs.call(void 0, "div",{className:"rle-list",children:[_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.x,{className:"rle-list-grid"}),_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.z,{})]}),n&&_jsxruntime.jsx.call(void 0, "div",{className:"rle-map",children:_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.y,{center:a,zoom:l,fallback:Oe})})]}),n&&_jsxruntime.jsx.call(void 0, me,{view:w,onViewChange:M}),_jsxruntime.jsx.call(void 0, ye,{title:"Filters",open:P,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:_,children:"Clear all"}),_jsxruntime.jsxs.call(void 0, "button",{type:"button",className:"rle-btn rle-btn--primary",onClick:()=>c(!1),children:["Show ",E," results"]})]}),children:_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.v,{className:"rle-filter-stack",groupClassName:"rle-filter-group"})})]})}function Ne(e){return"provider"in e}function Ze(e){let r=e!=null&&!Ne(e),t=r?e.apiKey:void 0,i=r?e.mapId:void 0,[n,a]=_react.useState.call(void 0, ()=>!e||Ne(e)?{ready:!0,provider:_optionalChain([e, 'optionalAccess', _5 => _5.provider])}:{ready:!1});return _react.useEffect.call(void 0, ()=>{if(!t)return;let l=!1;return Promise.resolve().then(() => _interopRequireWildcard(require("./maps/google/index.cjs"))).then(({googleProvider:m})=>{l||a({ready:!0,provider:m({apiKey:t,mapId:i})})}),()=>{l=!0}},[t,i]),n}function qe({onFiltersChange:e}){let r=_react.useRef.call(void 0, e);return r.current=e,ae("FiltersChanged",t=>{t.type==="FiltersChanged"&&r.current(t.filters)}),null}function ir(e){let{datasets:r,filters:t,map:i,components:n,initialFilters:a,onFiltersChange:l,mobileAction:m,search:p,toolbarEnd:h,config:d,autoFetch:S,className:w}=e,{ready:M,provider:P}=Ze(i);if(!M)return null;let c=[];for(let E of r)c.push(_chunkEYXV5OMYcjs.k.call(void 0, E));t&&c.push(_chunkEYXV5OMYcjs.l.call(void 0, t)),P&&c.push(_chunkEYXV5OMYcjs.j.call(void 0, P)),a&&c.push(_chunkEYXV5OMYcjs.n.call(void 0, a)),d&&c.push(_chunkEYXV5OMYcjs.i.call(void 0, d));let f=_chunkEYXV5OMYcjs.h.call(void 0, ...c),_={...ce,...n};return _jsxruntime.jsxs.call(void 0, _chunkEYXV5OMYcjs.B,{...f,children:[l&&_jsxruntime.jsx.call(void 0, qe,{onFiltersChange:l}),_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.p,{..._,children:_jsxruntime.jsx.call(void 0, Le,{className:w,search:p,toolbarEnd:h,mobileAction:m,autoFetch:S,hasMap:i!=null,mapCenter:_optionalChain([i, 'optionalAccess', _6 => _6.center]),mapZoom:_optionalChain([i, 'optionalAccess', _7 => _7.zoom])})})]})}exports.a = ae; exports.b = B; exports.c = A; exports.d = V; exports.e = K; exports.f = H; exports.g = O; exports.h = W; exports.i = $; exports.j = z; exports.k = U; exports.l = ce; exports.m = me; exports.n = ye; exports.o = Le; exports.p = ir;