@mapfirst.ai/react 0.0.7 → 0.0.8

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/dist/index.js CHANGED
@@ -1,2 +1,11 @@
1
- "use strict";var m=Object.create;var g=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var C=Object.getPrototypeOf,P=Object.prototype.hasOwnProperty;var E=(e,t)=>{for(var a in t)g(e,a,{get:t[a],enumerable:!0})},S=(e,t,a,l)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of M(t))!P.call(e,n)&&n!==a&&g(e,n,{get:()=>t[n],enumerable:!(l=h(t,n))||l.enumerable});return e};var k=(e,t,a)=>(a=e!=null?m(C(e)):{},S(t||!e||!e.__esModule?g(a,"default",{value:e,enumerable:!0}):a,e)),R=e=>S(g({},"__esModule",{value:!0}),e);var q={};E(q,{MarkerDebugList:()=>O,useGoogleMapsAttachment:()=>A,useMapFirst:()=>v,useMapFirstCore:()=>x,useMapFirstProperties:()=>F,useMapFirstSelectedProperty:()=>w,useMapLibreAttachment:()=>I,useMapboxAttachment:()=>_,usePrimaryType:()=>L,usePropertiesSearch:()=>B,useSelectedMarker:()=>T,useSmartFilterSearch:()=>N});module.exports=R(q);var u=k(require("react")),d=require("@mapfirst.ai/core"),f=require("react/jsx-runtime");function x(e){let t=u.default.useRef(null),[a,l]=u.default.useState(null),n=u.default.useRef(e);return u.default.useEffect(()=>{n.current=e}),u.default.useEffect(()=>{let y=n.current,p={adapter:null,...y,callbacks:{...y.callbacks,onPropertiesChange:o=>{var r,s;l(c=>c?{...c,properties:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onPropertiesChange)==null||s.call(r,o)},onSelectedPropertyChange:o=>{var r,s;l(c=>c?{...c,selectedPropertyId:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onSelectedPropertyChange)==null||s.call(r,o)},onPrimaryTypeChange:o=>{var r,s;l(c=>c?{...c,primary:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onPrimaryTypeChange)==null||s.call(r,o)},onFiltersChange:o=>{var r,s;l(c=>c?{...c,filters:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onFiltersChange)==null||s.call(r,o)},onBoundsChange:o=>{var r,s;l(c=>c?{...c,bounds:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onBoundsChange)==null||s.call(r,o)},onCenterChange:(o,r)=>{var s,c;l(b=>b?{...b,center:o,zoom:r}:null),(c=(s=n.current.callbacks)==null?void 0:s.onCenterChange)==null||c.call(s,o,r)},onZoomChange:o=>{var r,s;l(c=>c?{...c,zoom:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onZoomChange)==null||s.call(r,o)},onActiveLocationChange:o=>{var r,s;l(c=>c?{...c,activeLocation:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onActiveLocationChange)==null||s.call(r,o)},onLoadingStateChange:o=>{var r,s;l(c=>c?{...c,initialLoading:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onLoadingStateChange)==null||s.call(r,o)},onSearchingStateChange:o=>{var r,s;l(c=>c?{...c,isSearching:o}:null),(s=(r=n.current.callbacks)==null?void 0:r.onSearchingStateChange)==null||s.call(r,o)}}},i=new d.MapFirstCore(p);return t.current=i,l(i.getState()),()=>{i.destroy(),t.current=null,l(null)}},[]),{mapFirst:t.current,state:a}}function F(e){let[t,a]=u.default.useState([]);return u.default.useEffect(()=>{if(!e){a([]);return}a(e.getState().properties)},[e]),t}function w(e){let[t,a]=u.default.useState(null);return u.default.useEffect(()=>{if(!e){a(null);return}a(e.getState().selectedPropertyId)},[e]),t}function L(e){let[t,a]=u.default.useState("Accommodation");u.default.useEffect(()=>{if(!e){a("Accommodation");return}a(e.getState().primary)},[e]);let l=u.default.useCallback(n=>{e&&(e.setPrimaryType(n),a(n))},[e]);return[t,l]}function T(e){let[t,a]=u.default.useState(null);u.default.useEffect(()=>{if(!e){a(null);return}a(e.getState().selectedPropertyId)},[e]);let l=u.default.useCallback(n=>{e&&e.setSelectedMarker(n)},[e]);return[t,l]}function I({mapFirst:e,map:t,maplibregl:a,onMarkerClick:l}){let n=u.default.useRef(!1);u.default.useEffect(()=>{!e||!t||n.current||(e.attachMap(t,{platform:"maplibre",maplibregl:a,onMarkerClick:l}),n.current=!0)},[e,t,a,l])}function A({mapFirst:e,map:t,google:a,onMarkerClick:l}){let n=u.default.useRef(!1);u.default.useEffect(()=>{!e||!t||n.current||(e.attachMap(t,{platform:"google",google:a,onMarkerClick:l}),n.current=!0)},[e,t,a,l])}function _({mapFirst:e,map:t,mapboxgl:a,onMarkerClick:l}){let n=u.default.useRef(!1);u.default.useEffect(()=>{!e||!t||n.current||(e.attachMap(t,{platform:"mapbox",mapboxgl:a,onMarkerClick:l}),n.current=!0)},[e,t,a,l])}function v(e){let t=u.default.useRef(null);return u.default.useEffect(()=>{if(!e)return;let a=new d.MapFirstCore(e);return t.current=a,()=>{a.destroy(),t.current=null}},[e]),t}function B(e){let[t,a]=u.default.useState(!1),[l,n]=u.default.useState(null);return{search:u.default.useCallback(async p=>{if(!e){let i=new Error("MapFirst instance not available");throw n(i),i}a(!0),n(null);try{return await e.runPropertiesSearch({...p,onError:o=>{let r=o instanceof Error?o:new Error(String(o));n(r)}})}catch(i){let o=i instanceof Error?i:new Error(String(i));throw n(o),o}finally{a(!1)}},[e]),isLoading:t,error:l}}function N(e){let[t,a]=u.default.useState(!1),[l,n]=u.default.useState(null);return{search:u.default.useCallback(async p=>{if(!e){let i=new Error("MapFirst instance not available");throw n(i),i}a(!0),n(null);try{return await e.runSmartFilterSearch({...p,onError:o=>{let r=o instanceof Error?o:new Error(String(o));n(r)}})}catch(i){let o=i instanceof Error?i:new Error(String(i));throw n(o),o}finally{a(!1)}},[e]),isLoading:t,error:l}}function O({markers:e}){return(0,f.jsxs)("div",{style:{fontFamily:"sans-serif",fontSize:14},children:[(0,f.jsx)("strong",{children:"Markers"}),(0,f.jsx)("ul",{children:e.map(t=>{var a,l,n,y,p,i;return(0,f.jsxs)("li",{children:[t.name," \u2014 ",(n=(l=(a=t.location)==null?void 0:a.lat)==null?void 0:l.toFixed(3))!=null?n:"n/a",","," ",(i=(p=(y=t.location)==null?void 0:y.lon)==null?void 0:p.toFixed(3))!=null?i:"n/a"]},String(t.tripadvisor_id))})})]})}0&&(module.exports={MarkerDebugList,useGoogleMapsAttachment,useMapFirst,useMapFirstCore,useMapFirstProperties,useMapFirstSelectedProperty,useMapLibreAttachment,useMapboxAttachment,usePrimaryType,usePropertiesSearch,useSelectedMarker,useSmartFilterSearch});
1
+ "use strict";var Ee=Object.create;var J=Object.defineProperty;var Me=Object.getOwnPropertyDescriptor;var Ie=Object.getOwnPropertyNames;var Te=Object.getPrototypeOf,Be=Object.prototype.hasOwnProperty;var He=(e,t)=>{for(var o in t)J(e,o,{get:t[o],enumerable:!0})},Se=(e,t,o,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of Ie(t))!Be.call(e,i)&&i!==o&&J(e,i,{get:()=>t[i],enumerable:!(s=Me(t,i))||s.enumerable});return e};var ee=(e,t,o)=>(o=e!=null?Ee(Te(e)):{},Se(t||!e||!e.__esModule?J(o,"default",{value:e,enumerable:!0}):o,e)),Ne=e=>Se(J({},"__esModule",{value:!0}),e);var kt={};He(kt,{AiIcon:()=>fe,Chip:()=>re,CloseIcon:()=>D,EditIcon:()=>G,FilterChips:()=>pe,MarkerDebugList:()=>Pt,MinRatingFilterChip:()=>Z,NextIcon:()=>te,PriceRangeFilterChip:()=>ie,RestaurantPriceLevelChip:()=>se,SearchIcon:()=>j,SmartFilter:()=>Le,StarIcon:()=>ye,TransformedQueryChip:()=>ae,createMinRatingFilterLabel:()=>_e,createPriceRangeFilterLabel:()=>Ve,formatRatingValue:()=>ne,renderStars:()=>Ce,useFilterScroll:()=>le,useGoogleMapsAttachment:()=>bt,useIsPortrait:()=>de,useMapFirst:()=>St,useMapFirstCore:()=>dt,useMapFirstProperties:()=>mt,useMapFirstSelectedProperty:()=>gt,useMapLibreAttachment:()=>ht,useMapboxAttachment:()=>xt,usePrimaryType:()=>ft,usePropertiesSearch:()=>vt,useSelectedMarker:()=>yt,useSmartFilterSearch:()=>Ct,useTranslation:()=>I});module.exports=Ne(kt);var g=ee(require("react")),xe=require("@mapfirst.ai/core");var $=require("react");var P=require("react/jsx-runtime"),j=({className:e,style:t})=>(0,P.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:[(0,P.jsx)("circle",{cx:"11",cy:"11",r:"8"}),(0,P.jsx)("path",{d:"m21 21-4.35-4.35"})]}),D=({className:e,style:t})=>(0,P.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:[(0,P.jsx)("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),(0,P.jsx)("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),G=({className:e,style:t})=>(0,P.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:[(0,P.jsx)("path",{d:"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"}),(0,P.jsx)("path",{d:"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"})]}),te=({className:e,style:t})=>(0,P.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:(0,P.jsx)("polyline",{points:"9 18 15 12 9 6"})}),fe=({className:e,style:t})=>(0,P.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:[(0,P.jsx)("path",{d:"M12 2L2 7l10 5 10-5-10-5z"}),(0,P.jsx)("path",{d:"M2 17l10 5 10-5"}),(0,P.jsx)("path",{d:"M2 12l10 5 10-5"})]}),ye=({className:e,style:t,fill:o="none"})=>(0,P.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:o,stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:(0,P.jsx)("polygon",{points:"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"})});var ce=ee(require("react"));var ve=ee(require("react"));var V=require("react/jsx-runtime"),De={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",paddingRight:"20px",border:"1px solid #03852e",display:"flex",alignItems:"center",gap:"8px",flexShrink:0,height:"34px"},Ae={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},ze={width:"17px",height:"17px"},re=({label:e,icon:t,remove:o,style:s})=>{let[i,p]=ve.default.useState(!1);return(0,V.jsxs)("div",{style:{...De,...s},children:[t&&(0,V.jsx)("span",{style:{display:"flex",alignItems:"center"},children:t}),(0,V.jsx)("span",{style:{whiteSpace:"nowrap"},children:e}),(0,V.jsx)("button",{style:{...Ae,backgroundColor:i?"#e5e5e5":"white"},onClick:o,onMouseEnter:()=>p(!0),onMouseLeave:()=>p(!1),"aria-label":"Remove filter",children:(0,V.jsx)(D,{style:ze})})]})};var be=require("react");var U=require("react"),We={"smartFilter.placeholder":"Search for hotels, restaurants, or attractions...","smartFilter.typingPrompt":"Type to search...","smartFilter.nav.previous":"Previous filters","smartFilter.nav.next":"Next filters","smartFilter.toast.locationRequired":"Please select a location first","smartFilter.clearAll":"Clear all","smartFilter.minRating.suffix":"+","smartFilter.minRating.label":"{{value}}+","smartFilter.minRating.remove":"Remove rating filter","smartFilter.minRating.setTo":"Set rating to {{rating}}","smartFilter.priceRange.label":"Price Range","smartFilter.priceRange.remove":"Remove price filter","smartFilter.priceRange.edit":"Edit price","smartFilter.transformedQuery.remove":"Remove search query","smartFilter.transformedQuery.edit":"Edit search query","smartFilter.restaurantPriceLevel.label":"Price Level","smartFilter.restaurantPriceLevel.remove":"Remove price level filter","smartFilter.restaurantPriceLevel.none":"Any","smartFilter.restaurantPriceLevel.options.cheapEats":"Cheap Eats","smartFilter.restaurantPriceLevel.options.midRange":"Mid Range","smartFilter.restaurantPriceLevel.options.fineDining":"Fine Dining"},Oe=(e,t="USD")=>new Intl.NumberFormat("en-US",{style:"currency",currency:t,minimumFractionDigits:0,maximumFractionDigits:0}).format(e),I=(e,t)=>{let[o,s]=(0,U.useState)("en"),i=(0,U.useCallback)((u,c)=>{let n={...We,...e}[u]||u;return c&&Object.keys(c).forEach(a=>{n=n.replace(new RegExp(`{{${a}}}`,"g"),String(c[a]))}),n},[e]),p=(0,U.useCallback)((u,c)=>t?t(u,c):Oe(u,c),[t]);return{t:i,locale:o,setLocale:s,formatCurrency:p}};var q=require("react/jsx-runtime"),Ce=e=>{let t=[],o=Math.floor(e),s=e%1!==0,i={display:"block",width:"12px",height:"12px",borderRadius:"50%",border:"1px solid #03852e",pointerEvents:"none"},p={...i,backgroundColor:"#03852e"},u={...i,background:"linear-gradient(90deg, #03852e 50%, transparent 50%)"};for(let r=0;r<o;r+=1)t.push((0,q.jsx)("span",{style:p},`full-${r}`));s&&t.push((0,q.jsx)("span",{style:u},"half"));let c=Math.max(0,5-Math.ceil(e));for(let r=0;r<c;r+=1)t.push((0,q.jsx)("span",{style:i},`empty-${r}`));return t},_e=(e,t)=>(0,q.jsxs)("span",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[(0,q.jsx)("span",{style:{display:"flex",gap:"1px",userSelect:"none"},children:Ce(e)})," ",t]}),ne=e=>e.toFixed(1),Ve=(e,t,o,s)=>`${s(e,o)} - ${s(t!=null?t:0,o)}`;var M=require("react/jsx-runtime"),qe={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",paddingRight:"20px",border:"1px solid #03852e",display:"flex",gap:"8px",alignItems:"center",justifyContent:"center",flexShrink:0,height:"34px"},Qe={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",transition:"background-color 0.2s"},Ke={display:"flex",gap:"1px",userSelect:"none"},he={display:"block",width:"12px",height:"12px",borderRadius:"50%",border:"1px solid #03852e",pointerEvents:"none"},oe={position:"absolute",top:0,height:"100%",cursor:"pointer",backgroundColor:"transparent",border:"none",padding:0},Z=({rating:e,onChange:t,onRemove:o,star:s=!1})=>{let[i,p]=(0,be.useState)(null),[u,c]=(0,be.useState)(!1),{t:r}=I(),n=i!=null?i:e,a=f=>s&&f?f.toString():r("smartFilter.minRating.label",{value:ne(f)}),l=r("smartFilter.minRating.remove"),m=f=>r("smartFilter.minRating.setTo",{rating:ne(f)}),F=f=>{let S=f+1;return n>=S?"full":n>=S-.5?"half":"empty"},v=f=>{p(null),f!==e&&t(f)},k=f=>{var x;let S=f.relatedTarget;(!S||!((x=f.currentTarget.closest("[data-min-rating-chip]"))!=null&&x.contains(S)))&&p(null)};return(0,M.jsxs)("div",{style:qe,"data-min-rating-chip":!0,children:[(0,M.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"4px"},onMouseLeave:()=>p(null),children:[(0,M.jsx)("div",{style:Ke,children:Array.from({length:5}).map((f,S)=>{let x=F(S),h=S+1,w=h-.5;if(s)return(0,M.jsxs)("div",{style:{position:"relative",width:"16px",height:"16px"},children:[(0,M.jsx)(ye,{fill:n>=h?"#03852e":"none",style:{width:"16px",height:"16px",pointerEvents:"none"}}),(0,M.jsx)("button",{type:"button",style:{...oe,left:0,width:"50%",borderRadius:"50% 0 0 50%"},onMouseEnter:()=>p(w),onFocus:()=>p(w),onBlur:k,onClick:()=>v(w),"aria-label":m(w),title:a(w)}),(0,M.jsx)("button",{type:"button",style:{...oe,left:"50%",width:"50%",borderRadius:"0 50% 50% 0"},onMouseEnter:()=>p(h),onFocus:()=>p(h),onBlur:k,onClick:()=>v(h),"aria-label":m(h),title:a(h)})]},S);let N=x==="full"?{...he,backgroundColor:"#03852e"}:he,_={...he,background:"linear-gradient(90deg, #03852e 50%, transparent 50%)"};return(0,M.jsxs)("div",{style:{position:"relative",width:"12px",height:"12px"},children:[(0,M.jsx)("span",{style:x==="half"?_:N}),(0,M.jsx)("button",{type:"button",style:{...oe,left:0,width:"50%",borderRadius:"50% 0 0 50%",outline:"2px solid transparent",outlineOffset:"1px"},onMouseEnter:()=>p(w),onFocus:()=>p(w),onBlur:k,onClick:()=>v(w),"aria-label":m(w),title:a(w)}),(0,M.jsx)("button",{type:"button",style:{...oe,left:"50%",width:"50%",borderRadius:"0 50% 50% 0",outline:"2px solid transparent",outlineOffset:"1px"},onMouseEnter:()=>p(h),onFocus:()=>p(h),onBlur:k,onClick:()=>v(h),"aria-label":m(h),title:a(h)})]},S)})}),(0,M.jsx)("span",{style:{whiteSpace:"nowrap"},children:a(n)})]}),(0,M.jsx)("button",{style:{...Qe,backgroundColor:u?"#e5e5e5":"white"},onClick:o,onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),"aria-label":l,title:l,children:(0,M.jsx)(D,{style:{width:"17px",height:"17px"}})})]})};var Q=require("react");var R=require("react/jsx-runtime"),$e={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",border:"1px solid #03852e",display:"flex",alignItems:"center",gap:"8px",flexShrink:0,height:"34px"},Ye={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",transition:"background-color 0.2s"},je={outline:"none",fontSize:"16px",backgroundColor:"transparent",borderRadius:"2px",padding:"2px 8px",width:"64px",textAlign:"center",border:"none"},Ge={padding:"4px",borderRadius:"50%",cursor:"pointer",transition:"background-color 0.2s",border:"none",backgroundColor:"transparent",color:"#737373",display:"flex",alignItems:"center",justifyContent:"center"},Pe=({boundary:e,label:t,value:o,placeholder:s,currency:i,isOptional:p=!1,showRemoveButton:u=!1,removeLabel:c,editLabel:r,showAddWhenEmpty:n=!1,onCommit:a,onRemove:l})=>{let[m,F]=(0,Q.useState)(o!==void 0?String(o):""),[v,k]=(0,Q.useState)(!1),[f,S]=(0,Q.useState)(!1),[x,h]=(0,Q.useState)(!1),w=o!==void 0;(0,Q.useEffect)(()=>{F(o!==void 0?String(o):""),k(!1)},[o]);let N=()=>{F(o!==void 0?String(o):"")},_=()=>{if(m.trim()===""){if(p){a(void 0),F("");return}N();return}let y=Number(m);if(!Number.isFinite(y)){N();return}let A=Math.max(0,y);if(A===o){N();return}a(A)};return(0,R.jsxs)("div",{style:$e,children:[(0,R.jsx)("span",{style:{fontSize:"10px",textTransform:"uppercase",fontWeight:600,letterSpacing:"0.05em"},children:t}),v?(0,R.jsx)("input",{value:m,onChange:y=>{let A=y.target.value.replace(/[^\d]/g,"");F(A)},onBlur:()=>{_(),k(!1)},onKeyDown:y=>{if(y.key==="Enter"){y.preventDefault(),y.currentTarget.blur(),k(!1);return}if(y.key==="Escape"){y.preventDefault(),N(),y.currentTarget.blur(),k(!1);return}y.key.length===1&&/[0-9]/.test(y.key)||y.key==="Backspace"||y.key==="Delete"||y.key==="Tab"||y.key==="ArrowLeft"||y.key==="ArrowRight"||y.key==="Home"||y.key==="End"||y.preventDefault()},placeholder:s,inputMode:"numeric",pattern:"[0-9]*","aria-label":t,style:je,autoFocus:!0}):w?(0,R.jsxs)("span",{style:{fontSize:"16px"},children:[i,o]}):n?(0,R.jsx)("button",{type:"button",style:{fontSize:"16px",color:"#737373",cursor:"pointer",border:"none",backgroundColor:"transparent",padding:0},onClick:()=>k(!0),"aria-label":r,children:"+"}):(0,R.jsx)("span",{style:{fontSize:"16px",color:"#737373"},children:"-"}),(!n||n&&v)&&(0,R.jsx)("span",{style:{color:"#737373",fontSize:"12px"},children:i}),!v&&(!n||w)&&(0,R.jsx)("button",{type:"button",style:{...Ge,backgroundColor:f?"#e5e5e5":"transparent"},"aria-label":r,title:r,onClick:()=>k(!0),onMouseEnter:()=>S(!0),onMouseLeave:()=>S(!1),children:(0,R.jsx)(G,{})}),u&&(0,R.jsx)("button",{style:{...Ye,backgroundColor:x?"#e5e5e5":"white"},onClick:l,onMouseEnter:()=>h(!0),onMouseLeave:()=>h(!1),"aria-label":c,title:c,children:(0,R.jsx)(D,{style:{width:"17px",height:"17px"}})})]})},ie=({priceRange:e,currency:t,onChange:o,onRemove:s})=>{let{t:i}=I(),p="Min",u="Max",c=i("smartFilter.priceRange.remove"),r=i("smartFilter.priceRange.edit"),n=(a,l)=>{let m={min:e.min,max:e.max};a==="min"?(m.min=l,l!==void 0&&e.max!==void 0&&l>e.max&&(m.max=l)):(m.max=l,l!==void 0&&e.min!==void 0&&l<e.min&&(m.min=l)),(m.min!==e.min||m.max!==e.max)&&o(m)};return(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)(Pe,{boundary:"min",label:p,value:e.min,currency:t,editLabel:r,showRemoveButton:e.min!==void 0&&e.min!==0,onCommit:a=>n("min",a),onRemove:s}),(0,R.jsx)(Pe,{boundary:"max",label:u,value:e.max,currency:t,isOptional:!0,showRemoveButton:e.max!==void 0,removeLabel:c,editLabel:r,showAddWhenEmpty:!0,onCommit:a=>n("max",a),onRemove:s})]})};var Re=ee(require("react"));var B=require("react/jsx-runtime"),Ue={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",paddingRight:"20px",border:"1px solid #03852e",display:"flex",alignItems:"center",gap:"16px",flexShrink:0,height:"34px"},Ze={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",transition:"background-color 0.2s"},ke=[{value:"Cheap Eats",key:"cheapEats"},{value:"Mid Range",key:"midRange"},{value:"Fine Dining",key:"fineDining"}],se=({values:e,onChange:t,onRemove:o})=>{let{t:s}=I(),[i,p]=Re.default.useState(!1),u=s("smartFilter.restaurantPriceLevel.label"),c=s("smartFilter.restaurantPriceLevel.remove"),r=s("smartFilter.restaurantPriceLevel.none"),n=a=>{let{value:l,checked:m}=a.target,F=l,v=new Set(e);m?v.add(F):v.delete(F);let k=ke.filter(f=>v.has(f.value)).map(f=>f.value);t(k)};return(0,B.jsxs)("div",{style:Ue,children:[(0,B.jsxs)("div",{style:{display:"flex",alignItems:"center",gap:"8px",flexWrap:"wrap"},children:[(0,B.jsx)("span",{style:{fontSize:"10px",textTransform:"uppercase",fontWeight:600,letterSpacing:"0.05em"},children:u}),(0,B.jsxs)("div",{style:{display:"flex",gap:"12px"},children:[ke.map(a=>{let l=s(`smartFilter.restaurantPriceLevel.options.${a.key}`),m=`price-level-${a.key}`;return(0,B.jsxs)("label",{htmlFor:m,style:{display:"flex",alignItems:"center",gap:"4px",fontSize:"12px",cursor:"pointer"},children:[(0,B.jsx)("input",{id:m,type:"checkbox",value:a.value,checked:e.includes(a.value),onChange:n,style:{accentColor:"#03852e",cursor:"pointer"}}),(0,B.jsx)("span",{children:l})]},a.value)}),e.length===0&&(0,B.jsx)("span",{style:{fontSize:"12px",color:"#737373"},children:r})]})]}),(0,B.jsx)("button",{style:{...Ze,backgroundColor:i?"#e5e5e5":"white"},onClick:o,onMouseEnter:()=>p(!0),onMouseLeave:()=>p(!1),"aria-label":c!=null?c:u,title:c!=null?c:u,children:(0,B.jsx)(D,{style:{width:"17px",height:"17px"}})})]})};var O=require("react");var z=require("react/jsx-runtime"),Xe={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",paddingRight:"20px",border:"1px solid #03852e",display:"flex",alignItems:"center",gap:"8px",flexShrink:0,userSelect:"none",height:"34px"},Je={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",transition:"background-color 0.2s"},et={backgroundColor:"#ececec",borderRadius:"2px",padding:"2px 8px",outline:"none",fontSize:"16px",minWidth:"8ch",border:"none"},tt={padding:"4px",borderRadius:"50%",cursor:"pointer",transition:"background-color 0.2s",color:"#737373",border:"none",backgroundColor:"transparent",display:"flex",alignItems:"center",justifyContent:"center"},ae=({value:e,onChange:t,onRemove:o})=>{let s=(0,O.useRef)(null),[i,p]=(0,O.useState)(e),[u,c]=(0,O.useState)(!1),[r,n]=(0,O.useState)(!1),[a,l]=(0,O.useState)(!1),{t:m}=I(),F=m("smartFilter.transformedQuery.remove"),v=m("smartFilter.transformedQuery.edit");(0,O.useEffect)(()=>{p(e),c(!1)},[e]);let k=()=>{let x=i.trim();if(!x.length){p(e);return}x!==e&&t(x)};return(0,z.jsxs)("div",{style:Xe,children:[(0,z.jsx)(j,{style:{width:"16px",height:"16px",color:"#03852e"}}),u?(0,z.jsx)("input",{ref:s,value:i,onChange:x=>{p(x.target.value)},onBlur:()=>{k(),c(!1)},onKeyDown:x=>{if(x.key==="Enter"){x.preventDefault(),x.currentTarget.blur();return}if(x.key==="Escape"){x.preventDefault(),p(e),x.currentTarget.blur();return}},"aria-label":v,style:et,autoFocus:!0}):(0,z.jsx)("span",{style:{fontSize:"16px"},children:e}),!u&&(0,z.jsx)("button",{type:"button",style:{...tt,backgroundColor:r?"#e5e5e5":"transparent"},"aria-label":v,title:v,onClick:()=>c(!0),onMouseEnter:()=>n(!0),onMouseLeave:()=>n(!1),children:(0,z.jsx)(G,{})}),(0,z.jsx)("button",{style:{...Je,backgroundColor:a?"#e5e5e5":"white"},onClick:o,onMouseEnter:()=>l(!0),onMouseLeave:()=>l(!1),"aria-label":F,title:F,children:(0,z.jsx)(D,{style:{width:"17px",height:"17px"}})})]})};var W=require("react"),le=e=>{let t=(0,W.useRef)(null),[o,s]=(0,W.useState)(!0),[i,p]=(0,W.useState)(!0),u=(0,W.useCallback)(()=>{let r=t.current;if(!r){s(!0),p(!0);return}let{scrollLeft:n,scrollWidth:a,clientWidth:l}=r;s(n<=0),p(n+l>=a-1)},[]);(0,W.useEffect)(()=>{let r=t.current;if(u(),!r)return;let n=()=>u();return r.addEventListener("scroll",n,{passive:!0}),window.addEventListener("resize",u),()=>{r.removeEventListener("scroll",n),window.removeEventListener("resize",u)}},[e,u]);let c=(0,W.useCallback)(r=>{let n=t.current;if(!n)return;let a=n.clientWidth*.7;n.scrollBy({left:r==="next"?a:-a,behavior:"smooth"})},[]);return{scrollerRef:t,atStart:o,atEnd:i,scrollByDir:c}};var C=require("react/jsx-runtime"),rt={position:"relative",width:"100%"},nt={display:"flex",gap:"8px",overflowX:"auto",alignItems:"center",width:"100%",scrollbarWidth:"none",msOverflowStyle:"none"},Fe={pointerEvents:"none",position:"absolute",top:0,bottom:0,width:"40px"},we={position:"absolute",top:"50%",transform:"translateY(-50%)",backgroundColor:"white",color:"#003c30",border:"1px solid #003c30",padding:"4px",borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 1px 3px rgba(0,0,0,0.1)",cursor:"pointer"},pe=({filters:e,isPortrait:t,currency:o,minRatingSuffix:s,clearAllLabel:i,previousFiltersLabel:p,nextFiltersLabel:u,formatCurrency:c,onFilterChange:r,onResetFilters:n,onClearAll:a})=>{let{scrollerRef:l,atStart:m,atEnd:F,scrollByDir:v}=le(e.length),{t:k}=I(),[f,S]=ce.default.useState(null),[x,h]=ce.default.useState(!1),[w,N]=ce.default.useState(!1),_={...nt,padding:t?"8px 16px":"8px"};return(0,C.jsxs)("div",{style:rt,children:[(0,C.jsxs)("div",{ref:l,style:{..._,WebkitOverflowScrolling:"touch"},children:[(0,C.jsx)("style",{children:`
2
+ div::-webkit-scrollbar {
3
+ display: none;
4
+ }
5
+ `}),(0,C.jsx)("button",{style:{flexShrink:0,backgroundColor:x?"#03a03e":"#03852e",borderRadius:"50%",padding:"8px",cursor:"pointer",border:"none",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},onClick:n,onMouseEnter:()=>h(!0),onMouseLeave:()=>h(!1),children:(0,C.jsx)(j,{style:{width:"20px",height:"20px",color:"white"}})}),e.map(d=>{var y,A,X;let K=()=>(0,C.jsx)(re,{label:d.label,icon:d.icon,remove:()=>{r(e.filter(b=>b.id!==d.id))}},d.id);if(d.type==="minRating"){let b=(y=d.numericValue)!=null?y:Number(d.value);return Number.isFinite(b)?(0,C.jsx)(Z,{rating:b,onChange:L=>{let E=e.map(T=>T.id===d.id?{...T,numericValue:L,value:String(L)}:T);r(E)},onRemove:()=>void r(e.filter(L=>L.id!==d.id))},d.id):K()}if(d.type==="starRating"){let b=(A=d.numericValue)!=null?A:Number(d.value);return Number.isFinite(b)?(0,C.jsx)(Z,{star:!0,rating:b,onChange:L=>{let E=e.map(T=>T.id===d.id?{...T,numericValue:L,value:String(L)}:T);r(E)},onRemove:()=>void r(e.filter(L=>L.id!==d.id))},d.id):K()}return d.type==="priceRange"&&d.priceRange?(0,C.jsx)(ie,{priceRange:d.priceRange,currency:o,onChange:b=>{let L=e.map(E=>E.id===d.id?{...E,priceRange:b}:E);r(L)},onRemove:()=>void r(e.filter(b=>b.id!==d.id))},d.id):d.type==="transformed_query"?(0,C.jsx)(ae,{value:d.value,onChange:b=>{let L=e.map(E=>E.id===d.id?{...E,value:b}:E);r(L)},onRemove:()=>void r(e.filter(b=>b.id!==d.id))},d.id):d.type==="selected_restaurant_price_levels"?(0,C.jsx)(se,{values:(X=d.priceLevels)!=null?X:[],onChange:b=>{let L=e.map(E=>E.id===d.id?{...E,priceLevels:b}:E);r(L)},onRemove:()=>void r(e.filter(b=>b.id!==d.id))},d.id):K()}),(0,C.jsx)("button",{style:{flexShrink:0,padding:"4px 16px",borderRadius:"9999px",cursor:"pointer",fontSize:"14px",userSelect:"none",border:"none",backgroundColor:w?"#e5e5e5":"transparent",transition:"background-color 0.2s"},onClick:a,onMouseEnter:()=>N(!0),onMouseLeave:()=>N(!1),children:i})]}),!m&&(0,C.jsx)("div",{"aria-hidden":"true",style:{...Fe,left:0,background:"linear-gradient(to right, white, transparent)"}}),!F&&(0,C.jsx)("div",{"aria-hidden":"true",style:{...Fe,right:0,background:"linear-gradient(to left, white, transparent)"}}),!m&&(0,C.jsx)("button",{type:"button","aria-label":p,style:{...we,left:"4px",transform:"translateY(-50%) rotate(180deg)",backgroundColor:f==="prev"?"#e5e5e5":"white"},onClick:()=>v("prev"),onMouseEnter:()=>S("prev"),onMouseLeave:()=>S(null),children:(0,C.jsx)(te,{style:{width:"20px",height:"20px"}})}),!F&&(0,C.jsx)("button",{type:"button","aria-label":u,style:{...we,right:"4px",backgroundColor:f==="next"?"#e5e5e5":"white"},onClick:()=>v("next"),onMouseEnter:()=>S("next"),onMouseLeave:()=>S(null),children:(0,C.jsx)(te,{style:{width:"20px",height:"20px"}})})]})};var ue=require("react"),de=()=>{let[e,t]=(0,ue.useState)(typeof window!="undefined"?window.innerHeight>window.innerWidth:!1);return(0,ue.useEffect)(()=>{if(typeof window=="undefined")return;let o=()=>{t(window.innerHeight>window.innerWidth)};return window.addEventListener("resize",o),()=>window.removeEventListener("resize",o)},[]),e};var H=require("react/jsx-runtime"),ot={position:"relative",display:"flex",flexDirection:"column",gap:"8px",width:"100%"},it={position:"relative",display:"flex",alignItems:"center",gap:"8px",width:"100%"},st={position:"relative",display:"flex",alignItems:"center",flex:1,backgroundColor:"white",borderRadius:"24px",border:"1px solid #e5e5e5",padding:"12px 16px",boxShadow:"0 1px 3px rgba(0,0,0,0.1)"},at={width:"20px",height:"20px",color:"#03852e",flexShrink:0},lt={flex:1,border:"none",outline:"none",fontSize:"16px",backgroundColor:"transparent",color:"#000"},ct={position:"absolute",right:"16px",top:"50%",transform:"translateY(-50%)"},pt={width:"20px",height:"20px",border:"2px solid #e5e5e5",borderTop:"2px solid #03852e",borderRadius:"50%",animation:"spin 1s linear infinite"},ut={position:"absolute",left:"48px",top:"50%",transform:"translateY(-50%)",color:"#737373",pointerEvents:"none",fontSize:"16px"},Le=({mapFirst:e,filters:t,value:o,isSearching:s=!1,placeholder:i,onSearch:p,onFilterChange:u,onValueChange:c,showTypingPrompt:r=!0,customTranslations:n,currency:a="USD",style:l,inputStyle:m,containerStyle:F})=>{let[v,k]=(0,$.useState)(""),f=o!==void 0?o:v,S=c||k,x=de(),{t:h,formatCurrency:w}=I(n),N=h("smartFilter.minRating.suffix"),_=i||h("smartFilter.placeholder"),d=h("smartFilter.typingPrompt"),K=h("smartFilter.nav.previous"),y=h("smartFilter.nav.next"),A=h("smartFilter.clearAll"),X=async T=>{T.preventDefault();let me=f.trim();if(!(!me||s))try{await p(me)}catch(ge){console.error("Search error:",ge)}},b=(0,$.useCallback)(async(T,me)=>{if(!s)try{await u(T)}catch(ge){console.error("Filter change error:",ge)}},[s,u]),L=(0,$.useCallback)(()=>{b([])},[b]),E=(0,$.useCallback)(()=>{b([],!0),S("")},[b,S]);return(0,H.jsxs)("div",{style:{...ot,...F},children:[(0,H.jsx)("style",{children:`
6
+ @keyframes spin {
7
+ 0% { transform: rotate(0deg); }
8
+ 100% { transform: rotate(360deg); }
9
+ }
10
+ `}),(0,H.jsx)("form",{onSubmit:X,style:{...it,...l},children:(0,H.jsxs)("div",{style:st,children:[(0,H.jsx)(fe,{style:at}),(0,H.jsx)("input",{type:"text",value:f,onChange:T=>S(T.target.value),placeholder:_,disabled:s,style:{...lt,...m},autoComplete:"off","aria-label":"Smart search"}),r&&f.length===0&&!s&&(0,H.jsx)("span",{style:ut,children:d}),s&&(0,H.jsx)("div",{style:ct,children:(0,H.jsx)("div",{style:pt})})]})}),t.length>0&&(0,H.jsx)(pe,{filters:t,isPortrait:x,currency:a,minRatingSuffix:N,clearAllLabel:A,previousFiltersLabel:K,nextFiltersLabel:y,formatCurrency:w,onFilterChange:b,onResetFilters:L,onClearAll:E})]})};var Y=require("react/jsx-runtime");function dt(e){let t=g.default.useRef(null),[o,s]=g.default.useState(null),i=g.default.useRef(e);return g.default.useEffect(()=>{i.current=e}),g.default.useEffect(()=>{let p=i.current,u={adapter:null,...p,callbacks:{...p.callbacks,onPropertiesChange:r=>{var n,a;s(l=>l?{...l,properties:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onPropertiesChange)==null||a.call(n,r)},onSelectedPropertyChange:r=>{var n,a;s(l=>l?{...l,selectedPropertyId:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onSelectedPropertyChange)==null||a.call(n,r)},onPrimaryTypeChange:r=>{var n,a;s(l=>l?{...l,primary:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onPrimaryTypeChange)==null||a.call(n,r)},onFiltersChange:r=>{var n,a;s(l=>l?{...l,filters:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onFiltersChange)==null||a.call(n,r)},onBoundsChange:r=>{var n,a;s(l=>l?{...l,bounds:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onBoundsChange)==null||a.call(n,r)},onCenterChange:(r,n)=>{var a,l;s(m=>m?{...m,center:r,zoom:n}:null),(l=(a=i.current.callbacks)==null?void 0:a.onCenterChange)==null||l.call(a,r,n)},onZoomChange:r=>{var n,a;s(l=>l?{...l,zoom:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onZoomChange)==null||a.call(n,r)},onActiveLocationChange:r=>{var n,a;s(l=>l?{...l,activeLocation:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onActiveLocationChange)==null||a.call(n,r)},onLoadingStateChange:r=>{var n,a;s(l=>l?{...l,initialLoading:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onLoadingStateChange)==null||a.call(n,r)},onSearchingStateChange:r=>{var n,a;s(l=>l?{...l,isSearching:r}:null),(a=(n=i.current.callbacks)==null?void 0:n.onSearchingStateChange)==null||a.call(n,r)}}},c=new xe.MapFirstCore(u);return t.current=c,s(c.getState()),()=>{c.destroy(),t.current=null,s(null)}},[]),{mapFirst:t.current,state:o}}function mt(e){let[t,o]=g.default.useState([]);return g.default.useEffect(()=>{if(!e){o([]);return}o(e.getState().properties)},[e]),t}function gt(e){let[t,o]=g.default.useState(null);return g.default.useEffect(()=>{if(!e){o(null);return}o(e.getState().selectedPropertyId)},[e]),t}function ft(e){let[t,o]=g.default.useState("Accommodation");g.default.useEffect(()=>{if(!e){o("Accommodation");return}o(e.getState().primary)},[e]);let s=g.default.useCallback(i=>{e&&(e.setPrimaryType(i),o(i))},[e]);return[t,s]}function yt(e){let[t,o]=g.default.useState(null);g.default.useEffect(()=>{if(!e){o(null);return}o(e.getState().selectedPropertyId)},[e]);let s=g.default.useCallback(i=>{e&&e.setSelectedMarker(i)},[e]);return[t,s]}function ht({mapFirst:e,map:t,maplibregl:o,onMarkerClick:s}){let i=g.default.useRef(!1);g.default.useEffect(()=>{!e||!t||i.current||(e.attachMap(t,{platform:"maplibre",maplibregl:o,onMarkerClick:s}),i.current=!0)},[e,t,o,s])}function bt({mapFirst:e,map:t,google:o,onMarkerClick:s}){let i=g.default.useRef(!1);g.default.useEffect(()=>{!e||!t||i.current||(e.attachMap(t,{platform:"google",google:o,onMarkerClick:s}),i.current=!0)},[e,t,o,s])}function xt({mapFirst:e,map:t,mapboxgl:o,onMarkerClick:s}){let i=g.default.useRef(!1);g.default.useEffect(()=>{!e||!t||i.current||(e.attachMap(t,{platform:"mapbox",mapboxgl:o,onMarkerClick:s}),i.current=!0)},[e,t,o,s])}function St(e){let t=g.default.useRef(null);return g.default.useEffect(()=>{if(!e)return;let o=new xe.MapFirstCore(e);return t.current=o,()=>{o.destroy(),t.current=null}},[e]),t}function vt(e){let[t,o]=g.default.useState(!1),[s,i]=g.default.useState(null);return{search:g.default.useCallback(async u=>{if(!e){let c=new Error("MapFirst instance not available");throw i(c),c}o(!0),i(null);try{return await e.runPropertiesSearch({...u,onError:r=>{let n=r instanceof Error?r:new Error(String(r));i(n)}})}catch(c){let r=c instanceof Error?c:new Error(String(c));throw i(r),r}finally{o(!1)}},[e]),isLoading:t,error:s}}function Ct(e){let[t,o]=g.default.useState(!1),[s,i]=g.default.useState(null);return{search:g.default.useCallback(async u=>{if(!e){let c=new Error("MapFirst instance not available");throw i(c),c}o(!0),i(null);try{return await e.runSmartFilterSearch({...u,onError:r=>{let n=r instanceof Error?r:new Error(String(r));i(n)}})}catch(c){let r=c instanceof Error?c:new Error(String(c));throw i(r),r}finally{o(!1)}},[e]),isLoading:t,error:s}}function Pt({markers:e}){return(0,Y.jsxs)("div",{style:{fontFamily:"sans-serif",fontSize:14},children:[(0,Y.jsx)("strong",{children:"Markers"}),(0,Y.jsx)("ul",{children:e.map(t=>{var o,s,i,p,u,c;return(0,Y.jsxs)("li",{children:[t.name," \u2014 ",(i=(s=(o=t.location)==null?void 0:o.lat)==null?void 0:s.toFixed(3))!=null?i:"n/a",","," ",(c=(u=(p=t.location)==null?void 0:p.lon)==null?void 0:u.toFixed(3))!=null?c:"n/a"]},String(t.tripadvisor_id))})})]})}0&&(module.exports={AiIcon,Chip,CloseIcon,EditIcon,FilterChips,MarkerDebugList,MinRatingFilterChip,NextIcon,PriceRangeFilterChip,RestaurantPriceLevelChip,SearchIcon,SmartFilter,StarIcon,TransformedQueryChip,createMinRatingFilterLabel,createPriceRangeFilterLabel,formatRatingValue,renderStars,useFilterScroll,useGoogleMapsAttachment,useIsPortrait,useMapFirst,useMapFirstCore,useMapFirstProperties,useMapFirstSelectedProperty,useMapLibreAttachment,useMapboxAttachment,usePrimaryType,usePropertiesSearch,useSelectedMarker,useSmartFilterSearch,useTranslation});
2
11
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import React from \"react\";\nimport {\n MapFirstCore,\n type MapFirstOptions,\n type BaseMapFirstOptions,\n type Property,\n type MapLibreNamespace,\n type GoogleMapsNamespace,\n type MapboxNamespace,\n type MapState,\n type PropertyType,\n} from \"@mapfirst.ai/core\";\n\n// Import additional types for search functionality\ntype InitialRequestBody = {\n initial?: boolean;\n query?: string;\n bounds?: {\n sw: { lat: number; lng: number };\n ne: { lat: number; lng: number };\n };\n filters?: any;\n city?: string;\n country?: string;\n location_id?: number;\n longitude?: number;\n latitude?: number;\n radius?: number;\n};\n\ntype SmartFilter = {\n id: string;\n label: string;\n type:\n | \"amenity\"\n | \"hotelStyle\"\n | \"priceRange\"\n | \"minRating\"\n | \"starRating\"\n | \"primary_type\"\n | \"transformed_query\"\n | \"selected_restaurant_price_levels\";\n value: string;\n numericValue?: number;\n priceRange?: {\n min: number;\n max?: number;\n };\n propertyType?: PropertyType;\n priceLevels?: any[];\n};\n\n/**\n * Hook that creates a MapFirstCore instance that can be initialized before maps are ready.\n * Supports two-phase initialization: create SDK first, attach map later.\n * Returns the instance and reactive state that updates when SDK state changes.\n *\n * @example\n * ```tsx\n * // Phase 1: Create SDK instance with location data\n * const { mapFirst, state } = useMapFirstCore({\n * initialLocationData: {\n * city: \"New York\",\n * country: \"United States\",\n * currency: \"USD\"\n * }\n * });\n *\n * // Access reactive state\n * console.log(state.properties); // Updates when properties change\n * console.log(state.isSearching); // Updates when search state changes\n *\n * // Phase 2: Attach map when ready\n * useEffect(() => {\n * if (mapLibreInstance && mapFirst) {\n * mapFirst.attachMap(mapLibreInstance, {\n * platform: \"maplibre\",\n * maplibregl: maplibregl,\n * onMarkerClick: (marker) => console.log(marker)\n * });\n * }\n * }, [mapLibreInstance, mapFirst]);\n * ```\n */\nexport function useMapFirstCore(options: BaseMapFirstOptions) {\n const instanceRef = React.useRef<MapFirstCore | null>(null);\n const [state, setState] = React.useState<MapState | null>(null);\n\n // Memoize the options to prevent recreation on every render\n const optionsRef = React.useRef(options);\n React.useEffect(() => {\n optionsRef.current = options;\n });\n\n React.useEffect(() => {\n const opts = optionsRef.current;\n\n // Create MapFirstCore instance without map using adapter-driven options\n const coreOptions: MapFirstOptions = {\n adapter: null as any, // Will be set when attachMap is called\n ...opts,\n callbacks: {\n ...opts.callbacks,\n // Add internal callbacks to trigger React re-renders\n onPropertiesChange: (properties) => {\n setState((prev) => (prev ? { ...prev, properties } : null));\n optionsRef.current.callbacks?.onPropertiesChange?.(properties);\n },\n onSelectedPropertyChange: (id) => {\n setState((prev) =>\n prev ? { ...prev, selectedPropertyId: id } : null\n );\n optionsRef.current.callbacks?.onSelectedPropertyChange?.(id);\n },\n onPrimaryTypeChange: (type) => {\n setState((prev) => (prev ? { ...prev, primary: type } : null));\n optionsRef.current.callbacks?.onPrimaryTypeChange?.(type);\n },\n onFiltersChange: (filters) => {\n setState((prev) => (prev ? { ...prev, filters } : null));\n optionsRef.current.callbacks?.onFiltersChange?.(filters);\n },\n onBoundsChange: (bounds) => {\n setState((prev) => (prev ? { ...prev, bounds } : null));\n optionsRef.current.callbacks?.onBoundsChange?.(bounds);\n },\n onCenterChange: (center, zoom) => {\n setState((prev) => (prev ? { ...prev, center, zoom } : null));\n optionsRef.current.callbacks?.onCenterChange?.(center, zoom);\n },\n onZoomChange: (zoom) => {\n setState((prev) => (prev ? { ...prev, zoom } : null));\n optionsRef.current.callbacks?.onZoomChange?.(zoom);\n },\n onActiveLocationChange: (location) => {\n setState((prev) =>\n prev ? { ...prev, activeLocation: location } : null\n );\n optionsRef.current.callbacks?.onActiveLocationChange?.(location);\n },\n onLoadingStateChange: (loading) => {\n setState((prev) =>\n prev ? { ...prev, initialLoading: loading } : null\n );\n optionsRef.current.callbacks?.onLoadingStateChange?.(loading);\n },\n onSearchingStateChange: (searching) => {\n setState((prev) =>\n prev ? { ...prev, isSearching: searching } : null\n );\n optionsRef.current.callbacks?.onSearchingStateChange?.(searching);\n },\n },\n };\n\n const instance = new MapFirstCore(coreOptions);\n instanceRef.current = instance;\n\n // Initialize state from SDK\n setState(instance.getState());\n\n return () => {\n instance.destroy();\n instanceRef.current = null;\n setState(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return { mapFirst: instanceRef.current, state };\n}\n\n/**\n * Hook to access reactive properties from MapFirst SDK.\n * Returns the current properties array that updates when properties change.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const properties = useMapFirstProperties(mapFirst);\n *\n * return <div>Found {properties.length} properties</div>;\n * ```\n */\nexport function useMapFirstProperties(\n mapFirst: MapFirstCore | null\n): Property[] {\n const [properties, setProperties] = React.useState<Property[]>([]);\n\n React.useEffect(() => {\n if (!mapFirst) {\n setProperties([]);\n return;\n }\n\n // Initialize with current state\n setProperties(mapFirst.getState().properties);\n }, [mapFirst]);\n\n return properties;\n}\n\n/**\n * Hook to access the selected property ID from MapFirst SDK.\n * Returns the currently selected property ID that updates when selection changes.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const selectedId = useMapFirstSelectedProperty(mapFirst);\n *\n * return <div>Selected: {selectedId || 'None'}</div>;\n * ```\n */\nexport function useMapFirstSelectedProperty(\n mapFirst: MapFirstCore | null\n): number | null {\n const [selectedId, setSelectedId] = React.useState<number | null>(null);\n\n React.useEffect(() => {\n if (!mapFirst) {\n setSelectedId(null);\n return;\n }\n\n // Initialize with current state\n setSelectedId(mapFirst.getState().selectedPropertyId);\n }, [mapFirst]);\n\n return selectedId;\n}\n\n/**\n * Hook to access and control the primary property type.\n * Returns the current primary type and a setter function.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const [primaryType, setPrimaryType] = usePrimaryType(mapFirst);\n *\n * return (\n * <select value={primaryType} onChange={(e) => setPrimaryType(e.target.value as PropertyType)}>\n * <option value=\"Accommodation\">Hotels</option>\n * <option value=\"Restaurant\">Restaurants</option>\n * <option value=\"Attraction\">Attractions</option>\n * </select>\n * );\n * ```\n */\nexport function usePrimaryType(\n mapFirst: MapFirstCore | null\n): [PropertyType, (type: PropertyType) => void] {\n const [primaryType, setPrimaryTypeState] =\n React.useState<PropertyType>(\"Accommodation\");\n\n React.useEffect(() => {\n if (!mapFirst) {\n setPrimaryTypeState(\"Accommodation\");\n return;\n }\n\n // Initialize with current state\n setPrimaryTypeState(mapFirst.getState().primary);\n }, [mapFirst]);\n\n const setPrimaryType = React.useCallback(\n (type: PropertyType) => {\n if (mapFirst) {\n mapFirst.setPrimaryType(type);\n setPrimaryTypeState(type);\n }\n },\n [mapFirst]\n );\n\n return [primaryType, setPrimaryType];\n}\n\n/**\n * Hook to access and control the selected marker.\n * Returns the current selected marker ID and a setter function.\n * Note: This hook requires the MapFirstCore instance. For simpler usage with reactive updates,\n * use state.selectedPropertyId from useMapFirstCore instead.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const [selectedMarker, setSelectedMarker] = useSelectedMarker(mapFirst);\n *\n * return (\n * <div>\n * <p>Selected: {selectedMarker || 'None'}</p>\n * <button onClick={() => setSelectedMarker(null)}>Clear Selection</button>\n * </div>\n * );\n * ```\n */\nexport function useSelectedMarker(\n mapFirst: MapFirstCore | null\n): [number | null, (id: number | null) => void] {\n const [selectedMarker, setSelectedMarkerState] = React.useState<\n number | null\n >(null);\n\n React.useEffect(() => {\n if (!mapFirst) {\n setSelectedMarkerState(null);\n return;\n }\n\n // Initialize with current state\n setSelectedMarkerState(mapFirst.getState().selectedPropertyId);\n }, [mapFirst]);\n\n const setSelectedMarker = React.useCallback(\n (id: number | null) => {\n if (mapFirst) {\n mapFirst.setSelectedMarker(id);\n }\n },\n [mapFirst]\n );\n\n return [selectedMarker, setSelectedMarker];\n}\n\n/**\n * Hook for MapLibre GL JS integration.\n * Automatically attaches the map when both the SDK instance and map are available.\n *\n * @example\n * ```tsx\n * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: \"Paris\", country: \"France\" } });\n * const mapRef = useRef<maplibregl.Map | null>(null);\n *\n * useMapLibreAttachment({\n * mapFirst,\n * map: mapRef.current,\n * maplibregl: maplibregl,\n * onMarkerClick: (marker) => console.log(marker)\n * });\n *\n * // Access reactive state\n * console.log(state?.properties);\n * ```\n */\nexport function useMapLibreAttachment({\n mapFirst,\n map,\n maplibregl,\n onMarkerClick,\n}: {\n mapFirst: MapFirstCore | null;\n map: any | null;\n maplibregl: MapLibreNamespace;\n onMarkerClick?: (marker: Property) => void;\n}) {\n const attachedRef = React.useRef(false);\n\n React.useEffect(() => {\n if (!mapFirst || !map || attachedRef.current) {\n return;\n }\n\n mapFirst.attachMap(map, {\n platform: \"maplibre\",\n maplibregl,\n onMarkerClick,\n });\n\n attachedRef.current = true;\n }, [mapFirst, map, maplibregl, onMarkerClick]);\n}\n\n/**\n * Hook for Google Maps integration.\n * Automatically attaches the map when both the SDK instance and map are available.\n *\n * @example\n * ```tsx\n * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: \"Tokyo\", country: \"Japan\" } });\n * const mapRef = useRef<google.maps.Map | null>(null);\n *\n * useGoogleMapsAttachment({\n * mapFirst,\n * map: mapRef.current,\n * google: window.google,\n * onMarkerClick: (marker) => console.log(marker)\n * });\n *\n * // Access reactive state\n * console.log(state?.isSearching);\n * ```\n */\nexport function useGoogleMapsAttachment({\n mapFirst,\n map,\n google,\n onMarkerClick,\n}: {\n mapFirst: MapFirstCore | null;\n map: any | null;\n google: GoogleMapsNamespace;\n onMarkerClick?: (marker: Property) => void;\n}) {\n const attachedRef = React.useRef(false);\n\n React.useEffect(() => {\n if (!mapFirst || !map || attachedRef.current) {\n return;\n }\n\n mapFirst.attachMap(map, {\n platform: \"google\",\n google,\n onMarkerClick,\n });\n\n attachedRef.current = true;\n }, [mapFirst, map, google, onMarkerClick]);\n}\n\n/**\n * Hook for Mapbox GL JS integration.\n * Automatically attaches the map when both the SDK instance and map are available.\n *\n * @example\n * ```tsx\n * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: \"London\", country: \"United Kingdom\" } });\n * const mapRef = useRef<mapboxgl.Map | null>(null);\n *\n * useMapboxAttachment({\n * mapFirst,\n * map: mapRef.current,\n * mapboxgl: mapboxgl,\n * onMarkerClick: (marker) => console.log(marker)\n * });\n *\n * // Access reactive state\n * console.log(state?.filters);\n * ```\n */\nexport function useMapboxAttachment({\n mapFirst,\n map,\n mapboxgl,\n onMarkerClick,\n}: {\n mapFirst: MapFirstCore | null;\n map: any | null;\n mapboxgl: MapboxNamespace;\n onMarkerClick?: (marker: Property) => void;\n}) {\n const attachedRef = React.useRef(false);\n\n React.useEffect(() => {\n if (!mapFirst || !map || attachedRef.current) {\n return;\n }\n\n mapFirst.attachMap(map, {\n platform: \"mapbox\",\n mapboxgl,\n onMarkerClick,\n });\n\n attachedRef.current = true;\n }, [mapFirst, map, mapboxgl, onMarkerClick]);\n}\n\n/**\n * Legacy hook that creates the MapFirstCore instance with a map immediately.\n * Use useMapFirstCore + useMap*Attachment hooks for better control.\n *\n * @deprecated Use useMapFirstCore and platform-specific attachment hooks instead\n */\nexport function useMapFirst(options: MapFirstOptions | null) {\n const instanceRef = React.useRef<MapFirstCore | null>(null);\n\n React.useEffect(() => {\n if (!options) {\n return undefined;\n }\n const instance = new MapFirstCore(options);\n instanceRef.current = instance;\n\n return () => {\n instance.destroy();\n instanceRef.current = null;\n };\n }, [options]);\n\n return instanceRef;\n}\n\n/**\n * Hook to run properties search with the MapFirst SDK.\n * Returns a function to trigger the search and loading state.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const { search, isLoading, error } = usePropertiesSearch(mapFirst);\n *\n * const handleSearch = async () => {\n * await search({\n * body: {\n * city: \"Paris\",\n * country: \"France\",\n * filters: {\n * checkIn: new Date(),\n * checkOut: new Date(Date.now() + 86400000),\n * numAdults: 2,\n * numRooms: 1\n * }\n * }\n * });\n * };\n * ```\n */\nexport function usePropertiesSearch(mapFirst: MapFirstCore | null) {\n const [isLoading, setIsLoading] = React.useState(false);\n const [error, setError] = React.useState<Error | null>(null);\n\n const search = React.useCallback(\n async (options: {\n body: InitialRequestBody;\n beforeApplyProperties?: (data: any) => {\n price?: any;\n limit?: number;\n };\n smartFiltersClearable?: boolean;\n }) => {\n if (!mapFirst) {\n const err = new Error(\"MapFirst instance not available\");\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await mapFirst.runPropertiesSearch({\n ...options,\n onError: (err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n },\n });\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [mapFirst]\n );\n\n return { search, isLoading, error };\n}\n\n/**\n * Hook to run smart filter search with the MapFirst SDK.\n * Returns a function to trigger the search and loading state.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const { search, isLoading, error } = useSmartFilterSearch(mapFirst);\n *\n * const handleSearch = async () => {\n * await search({\n * query: \"hotels near beach with pool\"\n * });\n * };\n *\n * // Or with filters\n * const handleFilterSearch = async () => {\n * await search({\n * filters: [\n * { id: \"pool\", label: \"Pool\", type: \"amenity\", value: \"pool\" },\n * { id: \"4star\", label: \"4 Star\", type: \"starRating\", value: \"4\", numericValue: 4 }\n * ]\n * });\n * };\n * ```\n */\nexport function useSmartFilterSearch(mapFirst: MapFirstCore | null) {\n const [isLoading, setIsLoading] = React.useState(false);\n const [error, setError] = React.useState<Error | null>(null);\n\n const search = React.useCallback(\n async (options: {\n query?: string;\n filters?: SmartFilter[];\n onProcessFilters?: (\n filters: any,\n location_id?: number\n ) => {\n smartFilters?: SmartFilter[];\n price?: any;\n limit?: number;\n language?: string;\n };\n }) => {\n if (!mapFirst) {\n const err = new Error(\"MapFirst instance not available\");\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await mapFirst.runSmartFilterSearch({\n ...options,\n onError: (err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n },\n });\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [mapFirst]\n );\n\n return { search, isLoading, error };\n}\n\n/**\n * Helper component that simply renders the markers it receives so non-React environments\n * can verify data flows before wiring the SDK into a map.\n */\nexport function MarkerDebugList({ markers }: { markers: Property[] }) {\n return (\n <div style={{ fontFamily: \"sans-serif\", fontSize: 14 }}>\n <strong>Markers</strong>\n <ul>\n {markers.map((marker) => (\n <li key={String(marker.tripadvisor_id)}>\n {marker.name} — {marker.location?.lat?.toFixed(3) ?? \"n/a\"},{\" \"}\n {marker.location?.lon?.toFixed(3) ?? \"n/a\"}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n"],"mappings":"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","names":["index_exports","__export","MarkerDebugList","useGoogleMapsAttachment","useMapFirst","useMapFirstCore","useMapFirstProperties","useMapFirstSelectedProperty","useMapLibreAttachment","useMapboxAttachment","usePrimaryType","usePropertiesSearch","useSelectedMarker","useSmartFilterSearch","__toCommonJS","import_react","import_core","import_jsx_runtime","options","instanceRef","React","state","setState","optionsRef","opts","coreOptions","properties","_a","_b","prev","id","type","filters","bounds","center","zoom","location","loading","searching","instance","mapFirst","setProperties","selectedId","setSelectedId","primaryType","setPrimaryTypeState","setPrimaryType","selectedMarker","setSelectedMarkerState","setSelectedMarker","map","maplibregl","onMarkerClick","attachedRef","google","mapboxgl","isLoading","setIsLoading","error","setError","err","markers","marker","_c","_d","_e","_f"]}
1
+ {"version":3,"sources":["../src/index.tsx","../src/components/SmartFilter.tsx","../src/components/Icons.tsx","../src/components/smart-filter/FilterChips.tsx","../src/components/smart-filter/Chip.tsx","../src/components/smart-filter/MinRatingFilterChip.tsx","../src/hooks/useTranslation.ts","../src/components/smart-filter/utils.tsx","../src/components/smart-filter/PriceRangeFilterChip.tsx","../src/components/smart-filter/RestaurantPriceLevelChip.tsx","../src/components/smart-filter/TransformedQueryChip.tsx","../src/hooks/useFilterScroll.ts","../src/hooks/useIsPortrait.ts"],"sourcesContent":["import React from \"react\";\nimport {\n MapFirstCore,\n type MapFirstOptions,\n type BaseMapFirstOptions,\n type Property,\n type MapLibreNamespace,\n type GoogleMapsNamespace,\n type MapboxNamespace,\n type MapState,\n type PropertyType,\n} from \"@mapfirst.ai/core\";\n\n// Export all components\nexport * from \"./components\";\n\n// Export all hooks\nexport * from \"./hooks\";\n\n// Import additional types for search functionality\ntype InitialRequestBody = {\n initial?: boolean;\n query?: string;\n bounds?: {\n sw: { lat: number; lng: number };\n ne: { lat: number; lng: number };\n };\n filters?: any;\n city?: string;\n country?: string;\n location_id?: number;\n longitude?: number;\n latitude?: number;\n radius?: number;\n};\n\ntype SmartFilter = {\n id: string;\n label: string;\n type:\n | \"amenity\"\n | \"hotelStyle\"\n | \"priceRange\"\n | \"minRating\"\n | \"starRating\"\n | \"primary_type\"\n | \"transformed_query\"\n | \"selected_restaurant_price_levels\";\n value: string;\n numericValue?: number;\n priceRange?: {\n min: number;\n max?: number;\n };\n propertyType?: PropertyType;\n priceLevels?: any[];\n};\n\n/**\n * Hook that creates a MapFirstCore instance that can be initialized before maps are ready.\n * Supports two-phase initialization: create SDK first, attach map later.\n * Returns the instance and reactive state that updates when SDK state changes.\n *\n * @example\n * ```tsx\n * // Phase 1: Create SDK instance with location data\n * const { mapFirst, state } = useMapFirstCore({\n * initialLocationData: {\n * city: \"New York\",\n * country: \"United States\",\n * currency: \"USD\"\n * }\n * });\n *\n * // Access reactive state\n * console.log(state.properties); // Updates when properties change\n * console.log(state.isSearching); // Updates when search state changes\n *\n * // Phase 2: Attach map when ready\n * useEffect(() => {\n * if (mapLibreInstance && mapFirst) {\n * mapFirst.attachMap(mapLibreInstance, {\n * platform: \"maplibre\",\n * maplibregl: maplibregl,\n * onMarkerClick: (marker) => console.log(marker)\n * });\n * }\n * }, [mapLibreInstance, mapFirst]);\n * ```\n */\nexport function useMapFirstCore(options: BaseMapFirstOptions) {\n const instanceRef = React.useRef<MapFirstCore | null>(null);\n const [state, setState] = React.useState<MapState | null>(null);\n\n // Memoize the options to prevent recreation on every render\n const optionsRef = React.useRef(options);\n React.useEffect(() => {\n optionsRef.current = options;\n });\n\n React.useEffect(() => {\n const opts = optionsRef.current;\n\n // Create MapFirstCore instance without map using adapter-driven options\n const coreOptions: MapFirstOptions = {\n adapter: null as any, // Will be set when attachMap is called\n ...opts,\n callbacks: {\n ...opts.callbacks,\n // Add internal callbacks to trigger React re-renders\n onPropertiesChange: (properties) => {\n setState((prev) => (prev ? { ...prev, properties } : null));\n optionsRef.current.callbacks?.onPropertiesChange?.(properties);\n },\n onSelectedPropertyChange: (id) => {\n setState((prev) =>\n prev ? { ...prev, selectedPropertyId: id } : null\n );\n optionsRef.current.callbacks?.onSelectedPropertyChange?.(id);\n },\n onPrimaryTypeChange: (type) => {\n setState((prev) => (prev ? { ...prev, primary: type } : null));\n optionsRef.current.callbacks?.onPrimaryTypeChange?.(type);\n },\n onFiltersChange: (filters) => {\n setState((prev) => (prev ? { ...prev, filters } : null));\n optionsRef.current.callbacks?.onFiltersChange?.(filters);\n },\n onBoundsChange: (bounds) => {\n setState((prev) => (prev ? { ...prev, bounds } : null));\n optionsRef.current.callbacks?.onBoundsChange?.(bounds);\n },\n onCenterChange: (center, zoom) => {\n setState((prev) => (prev ? { ...prev, center, zoom } : null));\n optionsRef.current.callbacks?.onCenterChange?.(center, zoom);\n },\n onZoomChange: (zoom) => {\n setState((prev) => (prev ? { ...prev, zoom } : null));\n optionsRef.current.callbacks?.onZoomChange?.(zoom);\n },\n onActiveLocationChange: (location) => {\n setState((prev) =>\n prev ? { ...prev, activeLocation: location } : null\n );\n optionsRef.current.callbacks?.onActiveLocationChange?.(location);\n },\n onLoadingStateChange: (loading) => {\n setState((prev) =>\n prev ? { ...prev, initialLoading: loading } : null\n );\n optionsRef.current.callbacks?.onLoadingStateChange?.(loading);\n },\n onSearchingStateChange: (searching) => {\n setState((prev) =>\n prev ? { ...prev, isSearching: searching } : null\n );\n optionsRef.current.callbacks?.onSearchingStateChange?.(searching);\n },\n },\n };\n\n const instance = new MapFirstCore(coreOptions);\n instanceRef.current = instance;\n\n // Initialize state from SDK\n setState(instance.getState());\n\n return () => {\n instance.destroy();\n instanceRef.current = null;\n setState(null);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return { mapFirst: instanceRef.current, state };\n}\n\n/**\n * Hook to access reactive properties from MapFirst SDK.\n * Returns the current properties array that updates when properties change.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const properties = useMapFirstProperties(mapFirst);\n *\n * return <div>Found {properties.length} properties</div>;\n * ```\n */\nexport function useMapFirstProperties(\n mapFirst: MapFirstCore | null\n): Property[] {\n const [properties, setProperties] = React.useState<Property[]>([]);\n\n React.useEffect(() => {\n if (!mapFirst) {\n setProperties([]);\n return;\n }\n\n // Initialize with current state\n setProperties(mapFirst.getState().properties);\n }, [mapFirst]);\n\n return properties;\n}\n\n/**\n * Hook to access the selected property ID from MapFirst SDK.\n * Returns the currently selected property ID that updates when selection changes.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const selectedId = useMapFirstSelectedProperty(mapFirst);\n *\n * return <div>Selected: {selectedId || 'None'}</div>;\n * ```\n */\nexport function useMapFirstSelectedProperty(\n mapFirst: MapFirstCore | null\n): number | null {\n const [selectedId, setSelectedId] = React.useState<number | null>(null);\n\n React.useEffect(() => {\n if (!mapFirst) {\n setSelectedId(null);\n return;\n }\n\n // Initialize with current state\n setSelectedId(mapFirst.getState().selectedPropertyId);\n }, [mapFirst]);\n\n return selectedId;\n}\n\n/**\n * Hook to access and control the primary property type.\n * Returns the current primary type and a setter function.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const [primaryType, setPrimaryType] = usePrimaryType(mapFirst);\n *\n * return (\n * <select value={primaryType} onChange={(e) => setPrimaryType(e.target.value as PropertyType)}>\n * <option value=\"Accommodation\">Hotels</option>\n * <option value=\"Restaurant\">Restaurants</option>\n * <option value=\"Attraction\">Attractions</option>\n * </select>\n * );\n * ```\n */\nexport function usePrimaryType(\n mapFirst: MapFirstCore | null\n): [PropertyType, (type: PropertyType) => void] {\n const [primaryType, setPrimaryTypeState] =\n React.useState<PropertyType>(\"Accommodation\");\n\n React.useEffect(() => {\n if (!mapFirst) {\n setPrimaryTypeState(\"Accommodation\");\n return;\n }\n\n // Initialize with current state\n setPrimaryTypeState(mapFirst.getState().primary);\n }, [mapFirst]);\n\n const setPrimaryType = React.useCallback(\n (type: PropertyType) => {\n if (mapFirst) {\n mapFirst.setPrimaryType(type);\n setPrimaryTypeState(type);\n }\n },\n [mapFirst]\n );\n\n return [primaryType, setPrimaryType];\n}\n\n/**\n * Hook to access and control the selected marker.\n * Returns the current selected marker ID and a setter function.\n * Note: This hook requires the MapFirstCore instance. For simpler usage with reactive updates,\n * use state.selectedPropertyId from useMapFirstCore instead.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const [selectedMarker, setSelectedMarker] = useSelectedMarker(mapFirst);\n *\n * return (\n * <div>\n * <p>Selected: {selectedMarker || 'None'}</p>\n * <button onClick={() => setSelectedMarker(null)}>Clear Selection</button>\n * </div>\n * );\n * ```\n */\nexport function useSelectedMarker(\n mapFirst: MapFirstCore | null\n): [number | null, (id: number | null) => void] {\n const [selectedMarker, setSelectedMarkerState] = React.useState<\n number | null\n >(null);\n\n React.useEffect(() => {\n if (!mapFirst) {\n setSelectedMarkerState(null);\n return;\n }\n\n // Initialize with current state\n setSelectedMarkerState(mapFirst.getState().selectedPropertyId);\n }, [mapFirst]);\n\n const setSelectedMarker = React.useCallback(\n (id: number | null) => {\n if (mapFirst) {\n mapFirst.setSelectedMarker(id);\n }\n },\n [mapFirst]\n );\n\n return [selectedMarker, setSelectedMarker];\n}\n\n/**\n * Hook for MapLibre GL JS integration.\n * Automatically attaches the map when both the SDK instance and map are available.\n *\n * @example\n * ```tsx\n * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: \"Paris\", country: \"France\" } });\n * const mapRef = useRef<maplibregl.Map | null>(null);\n *\n * useMapLibreAttachment({\n * mapFirst,\n * map: mapRef.current,\n * maplibregl: maplibregl,\n * onMarkerClick: (marker) => console.log(marker)\n * });\n *\n * // Access reactive state\n * console.log(state?.properties);\n * ```\n */\nexport function useMapLibreAttachment({\n mapFirst,\n map,\n maplibregl,\n onMarkerClick,\n}: {\n mapFirst: MapFirstCore | null;\n map: any | null;\n maplibregl: MapLibreNamespace;\n onMarkerClick?: (marker: Property) => void;\n}) {\n const attachedRef = React.useRef(false);\n\n React.useEffect(() => {\n if (!mapFirst || !map || attachedRef.current) {\n return;\n }\n\n mapFirst.attachMap(map, {\n platform: \"maplibre\",\n maplibregl,\n onMarkerClick,\n });\n\n attachedRef.current = true;\n }, [mapFirst, map, maplibregl, onMarkerClick]);\n}\n\n/**\n * Hook for Google Maps integration.\n * Automatically attaches the map when both the SDK instance and map are available.\n *\n * @example\n * ```tsx\n * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: \"Tokyo\", country: \"Japan\" } });\n * const mapRef = useRef<google.maps.Map | null>(null);\n *\n * useGoogleMapsAttachment({\n * mapFirst,\n * map: mapRef.current,\n * google: window.google,\n * onMarkerClick: (marker) => console.log(marker)\n * });\n *\n * // Access reactive state\n * console.log(state?.isSearching);\n * ```\n */\nexport function useGoogleMapsAttachment({\n mapFirst,\n map,\n google,\n onMarkerClick,\n}: {\n mapFirst: MapFirstCore | null;\n map: any | null;\n google: GoogleMapsNamespace;\n onMarkerClick?: (marker: Property) => void;\n}) {\n const attachedRef = React.useRef(false);\n\n React.useEffect(() => {\n if (!mapFirst || !map || attachedRef.current) {\n return;\n }\n\n mapFirst.attachMap(map, {\n platform: \"google\",\n google,\n onMarkerClick,\n });\n\n attachedRef.current = true;\n }, [mapFirst, map, google, onMarkerClick]);\n}\n\n/**\n * Hook for Mapbox GL JS integration.\n * Automatically attaches the map when both the SDK instance and map are available.\n *\n * @example\n * ```tsx\n * const { mapFirst, state } = useMapFirstCore({ initialLocationData: { city: \"London\", country: \"United Kingdom\" } });\n * const mapRef = useRef<mapboxgl.Map | null>(null);\n *\n * useMapboxAttachment({\n * mapFirst,\n * map: mapRef.current,\n * mapboxgl: mapboxgl,\n * onMarkerClick: (marker) => console.log(marker)\n * });\n *\n * // Access reactive state\n * console.log(state?.filters);\n * ```\n */\nexport function useMapboxAttachment({\n mapFirst,\n map,\n mapboxgl,\n onMarkerClick,\n}: {\n mapFirst: MapFirstCore | null;\n map: any | null;\n mapboxgl: MapboxNamespace;\n onMarkerClick?: (marker: Property) => void;\n}) {\n const attachedRef = React.useRef(false);\n\n React.useEffect(() => {\n if (!mapFirst || !map || attachedRef.current) {\n return;\n }\n\n mapFirst.attachMap(map, {\n platform: \"mapbox\",\n mapboxgl,\n onMarkerClick,\n });\n\n attachedRef.current = true;\n }, [mapFirst, map, mapboxgl, onMarkerClick]);\n}\n\n/**\n * Legacy hook that creates the MapFirstCore instance with a map immediately.\n * Use useMapFirstCore + useMap*Attachment hooks for better control.\n *\n * @deprecated Use useMapFirstCore and platform-specific attachment hooks instead\n */\nexport function useMapFirst(options: MapFirstOptions | null) {\n const instanceRef = React.useRef<MapFirstCore | null>(null);\n\n React.useEffect(() => {\n if (!options) {\n return undefined;\n }\n const instance = new MapFirstCore(options);\n instanceRef.current = instance;\n\n return () => {\n instance.destroy();\n instanceRef.current = null;\n };\n }, [options]);\n\n return instanceRef;\n}\n\n/**\n * Hook to run properties search with the MapFirst SDK.\n * Returns a function to trigger the search and loading state.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const { search, isLoading, error } = usePropertiesSearch(mapFirst);\n *\n * const handleSearch = async () => {\n * await search({\n * body: {\n * city: \"Paris\",\n * country: \"France\",\n * filters: {\n * checkIn: new Date(),\n * checkOut: new Date(Date.now() + 86400000),\n * numAdults: 2,\n * numRooms: 1\n * }\n * }\n * });\n * };\n * ```\n */\nexport function usePropertiesSearch(mapFirst: MapFirstCore | null) {\n const [isLoading, setIsLoading] = React.useState(false);\n const [error, setError] = React.useState<Error | null>(null);\n\n const search = React.useCallback(\n async (options: {\n body: InitialRequestBody;\n beforeApplyProperties?: (data: any) => {\n price?: any;\n limit?: number;\n };\n smartFiltersClearable?: boolean;\n }) => {\n if (!mapFirst) {\n const err = new Error(\"MapFirst instance not available\");\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await mapFirst.runPropertiesSearch({\n ...options,\n onError: (err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n },\n });\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [mapFirst]\n );\n\n return { search, isLoading, error };\n}\n\n/**\n * Hook to run smart filter search with the MapFirst SDK.\n * Returns a function to trigger the search and loading state.\n *\n * @example\n * ```tsx\n * const { mapFirst } = useMapFirstCore({ ... });\n * const { search, isLoading, error } = useSmartFilterSearch(mapFirst);\n *\n * const handleSearch = async () => {\n * await search({\n * query: \"hotels near beach with pool\"\n * });\n * };\n *\n * // Or with filters\n * const handleFilterSearch = async () => {\n * await search({\n * filters: [\n * { id: \"pool\", label: \"Pool\", type: \"amenity\", value: \"pool\" },\n * { id: \"4star\", label: \"4 Star\", type: \"starRating\", value: \"4\", numericValue: 4 }\n * ]\n * });\n * };\n * ```\n */\nexport function useSmartFilterSearch(mapFirst: MapFirstCore | null) {\n const [isLoading, setIsLoading] = React.useState(false);\n const [error, setError] = React.useState<Error | null>(null);\n\n const search = React.useCallback(\n async (options: {\n query?: string;\n filters?: SmartFilter[];\n onProcessFilters?: (\n filters: any,\n location_id?: number\n ) => {\n smartFilters?: SmartFilter[];\n price?: any;\n limit?: number;\n language?: string;\n };\n }) => {\n if (!mapFirst) {\n const err = new Error(\"MapFirst instance not available\");\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await mapFirst.runSmartFilterSearch({\n ...options,\n onError: (err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n },\n });\n return result;\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [mapFirst]\n );\n\n return { search, isLoading, error };\n}\n\n/**\n * Helper component that simply renders the markers it receives so non-React environments\n * can verify data flows before wiring the SDK into a map.\n */\nexport function MarkerDebugList({ markers }: { markers: Property[] }) {\n return (\n <div style={{ fontFamily: \"sans-serif\", fontSize: 14 }}>\n <strong>Markers</strong>\n <ul>\n {markers.map((marker) => (\n <li key={String(marker.tripadvisor_id)}>\n {marker.name} — {marker.location?.lat?.toFixed(3) ?? \"n/a\"},{\" \"}\n {marker.location?.lon?.toFixed(3) ?? \"n/a\"}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n","import React, {\r\n FormEventHandler,\r\n FunctionComponent,\r\n useCallback,\r\n useState,\r\n CSSProperties,\r\n} from \"react\";\r\nimport { AiIcon } from \"./Icons\";\r\nimport { FilterChips } from \"./smart-filter/FilterChips\";\r\nimport { useIsPortrait } from \"../hooks/useIsPortrait\";\r\nimport { useTranslation } from \"../hooks/useTranslation\";\r\nimport type { Filter } from \"./smart-filter/types\";\r\nimport type {\r\n MapFirstCore,\r\n FilterSchema,\r\n PropertyType,\r\n PriceLevel,\r\n} from \"@mapfirst.ai/core\";\r\n\r\nexport interface SmartFilterProps {\r\n mapFirst: MapFirstCore | null;\r\n filters: Filter[];\r\n value?: string;\r\n isSearching?: boolean;\r\n placeholder?: string;\r\n onSearch: (query: string, filters?: Filter[]) => Promise<void> | void;\r\n onFilterChange: (filters: Filter[]) => Promise<void> | void;\r\n onValueChange?: (value: string) => void;\r\n showTypingPrompt?: boolean;\r\n customTranslations?: Record<string, string>;\r\n currency?: string;\r\n style?: CSSProperties;\r\n inputStyle?: CSSProperties;\r\n containerStyle?: CSSProperties;\r\n}\r\n\r\nconst containerStyles: CSSProperties = {\r\n position: \"relative\",\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: \"8px\",\r\n width: \"100%\",\r\n};\r\n\r\nconst formStyles: CSSProperties = {\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: \"8px\",\r\n width: \"100%\",\r\n};\r\n\r\nconst inputContainerStyles: CSSProperties = {\r\n position: \"relative\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n flex: 1,\r\n backgroundColor: \"white\",\r\n borderRadius: \"24px\",\r\n border: \"1px solid #e5e5e5\",\r\n padding: \"12px 16px\",\r\n boxShadow: \"0 1px 3px rgba(0,0,0,0.1)\",\r\n};\r\n\r\nconst iconStyles: CSSProperties = {\r\n width: \"20px\",\r\n height: \"20px\",\r\n color: \"#03852e\",\r\n flexShrink: 0,\r\n};\r\n\r\nconst inputStyles: CSSProperties = {\r\n flex: 1,\r\n border: \"none\",\r\n outline: \"none\",\r\n fontSize: \"16px\",\r\n backgroundColor: \"transparent\",\r\n color: \"#000\",\r\n};\r\n\r\nconst loaderContainerStyles: CSSProperties = {\r\n position: \"absolute\",\r\n right: \"16px\",\r\n top: \"50%\",\r\n transform: \"translateY(-50%)\",\r\n};\r\n\r\nconst loaderStyles: CSSProperties = {\r\n width: \"20px\",\r\n height: \"20px\",\r\n border: \"2px solid #e5e5e5\",\r\n borderTop: \"2px solid #03852e\",\r\n borderRadius: \"50%\",\r\n animation: \"spin 1s linear infinite\",\r\n};\r\n\r\nconst typingPromptStyles: CSSProperties = {\r\n position: \"absolute\",\r\n left: \"48px\",\r\n top: \"50%\",\r\n transform: \"translateY(-50%)\",\r\n color: \"#737373\",\r\n pointerEvents: \"none\",\r\n fontSize: \"16px\",\r\n};\r\n\r\n/**\r\n * SmartFilter component for AI-powered search with filter chips.\r\n * Provides a search input with smart filtering capabilities.\r\n *\r\n * @example\r\n * ```tsx\r\n * const { mapFirst, state } = useMapFirstCore({ ... });\r\n * const [filters, setFilters] = useState<Filter[]>([]);\r\n * const [searchValue, setSearchValue] = useState(\"\");\r\n *\r\n * const handleSearch = async (query: string, currentFilters?: Filter[]) => {\r\n * // Perform search using mapFirst.runSmartFilterSearch\r\n * const result = await mapFirst.runSmartFilterSearch({\r\n * query,\r\n * filters: currentFilters\r\n * });\r\n * // Update filters based on response\r\n * };\r\n *\r\n * return (\r\n * <SmartFilter\r\n * mapFirst={mapFirst}\r\n * filters={filters}\r\n * value={searchValue}\r\n * isSearching={state?.isSearching}\r\n * onSearch={handleSearch}\r\n * onFilterChange={setFilters}\r\n * onValueChange={setSearchValue}\r\n * />\r\n * );\r\n * ```\r\n */\r\nexport const SmartFilter: FunctionComponent<SmartFilterProps> = ({\r\n mapFirst,\r\n filters,\r\n value: controlledValue,\r\n isSearching = false,\r\n placeholder,\r\n onSearch,\r\n onFilterChange,\r\n onValueChange,\r\n showTypingPrompt = true,\r\n customTranslations,\r\n currency = \"USD\",\r\n style,\r\n inputStyle,\r\n containerStyle,\r\n}) => {\r\n const [internalValue, setInternalValue] = useState(\"\");\r\n const value = controlledValue !== undefined ? controlledValue : internalValue;\r\n const setValue = onValueChange || setInternalValue;\r\n\r\n const isPortrait = useIsPortrait();\r\n const { t, formatCurrency } = useTranslation(customTranslations);\r\n\r\n const minRatingSuffix = t(\"smartFilter.minRating.suffix\");\r\n const placeholderText = placeholder || t(\"smartFilter.placeholder\");\r\n const typingPrompt = t(\"smartFilter.typingPrompt\");\r\n const previousFiltersLabel = t(\"smartFilter.nav.previous\");\r\n const nextFiltersLabel = t(\"smartFilter.nav.next\");\r\n const clearAllLabel = t(\"smartFilter.clearAll\");\r\n\r\n const formSubmit: FormEventHandler<HTMLFormElement> = async (e) => {\r\n e.preventDefault();\r\n const query = value.trim();\r\n if (!query || isSearching) {\r\n return;\r\n }\r\n try {\r\n await onSearch(query);\r\n } catch (error) {\r\n console.error(\"Search error:\", error);\r\n }\r\n };\r\n\r\n const handleFilterChange = useCallback(\r\n async (nextFilters: Filter[], clearAll?: boolean) => {\r\n if (isSearching) {\r\n return;\r\n }\r\n try {\r\n await onFilterChange(nextFilters);\r\n } catch (error) {\r\n console.error(\"Filter change error:\", error);\r\n }\r\n },\r\n [isSearching, onFilterChange]\r\n );\r\n\r\n const resetFilters = useCallback(() => {\r\n void handleFilterChange([]);\r\n }, [handleFilterChange]);\r\n\r\n const clearAllFilters = useCallback(() => {\r\n void handleFilterChange([], true);\r\n setValue(\"\");\r\n }, [handleFilterChange, setValue]);\r\n\r\n return (\r\n <div style={{ ...containerStyles, ...containerStyle }}>\r\n <style>\r\n {`\r\n @keyframes spin {\r\n 0% { transform: rotate(0deg); }\r\n 100% { transform: rotate(360deg); }\r\n }\r\n `}\r\n </style>\r\n <form onSubmit={formSubmit} style={{ ...formStyles, ...style }}>\r\n <div style={inputContainerStyles}>\r\n <AiIcon style={iconStyles} />\r\n <input\r\n type=\"text\"\r\n value={value}\r\n onChange={(e) => setValue(e.target.value)}\r\n placeholder={placeholderText}\r\n disabled={isSearching}\r\n style={{ ...inputStyles, ...inputStyle }}\r\n autoComplete=\"off\"\r\n aria-label=\"Smart search\"\r\n />\r\n {showTypingPrompt && value.length === 0 && !isSearching && (\r\n <span style={typingPromptStyles}>{typingPrompt}</span>\r\n )}\r\n {isSearching && (\r\n <div style={loaderContainerStyles}>\r\n <div style={loaderStyles} />\r\n </div>\r\n )}\r\n </div>\r\n </form>\r\n\r\n {filters.length > 0 && (\r\n <FilterChips\r\n filters={filters}\r\n isPortrait={isPortrait}\r\n currency={currency}\r\n minRatingSuffix={minRatingSuffix}\r\n clearAllLabel={clearAllLabel}\r\n previousFiltersLabel={previousFiltersLabel}\r\n nextFiltersLabel={nextFiltersLabel}\r\n formatCurrency={formatCurrency}\r\n onFilterChange={handleFilterChange}\r\n onResetFilters={resetFilters}\r\n onClearAll={clearAllFilters}\r\n />\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { CSSProperties } from \"react\";\r\n\r\nexport interface IconProps {\r\n className?: string;\r\n style?: CSSProperties;\r\n}\r\n\r\nexport const SearchIcon: React.FC<IconProps> = ({ className, style }) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={className}\r\n style={{ width: \"1em\", height: \"1em\", ...style }}\r\n >\r\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\r\n <path d=\"m21 21-4.35-4.35\" />\r\n </svg>\r\n);\r\n\r\nexport const CloseIcon: React.FC<IconProps> = ({ className, style }) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={className}\r\n style={{ width: \"1em\", height: \"1em\", ...style }}\r\n >\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\r\n </svg>\r\n);\r\n\r\nexport const EditIcon: React.FC<IconProps> = ({ className, style }) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={className}\r\n style={{ width: \"1em\", height: \"1em\", ...style }}\r\n >\r\n <path d=\"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7\" />\r\n <path d=\"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z\" />\r\n </svg>\r\n);\r\n\r\nexport const NextIcon: React.FC<IconProps> = ({ className, style }) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={className}\r\n style={{ width: \"1em\", height: \"1em\", ...style }}\r\n >\r\n <polyline points=\"9 18 15 12 9 6\" />\r\n </svg>\r\n);\r\n\r\nexport const AiIcon: React.FC<IconProps> = ({ className, style }) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={className}\r\n style={{ width: \"1em\", height: \"1em\", ...style }}\r\n >\r\n <path d=\"M12 2L2 7l10 5 10-5-10-5z\" />\r\n <path d=\"M2 17l10 5 10-5\" />\r\n <path d=\"M2 12l10 5 10-5\" />\r\n </svg>\r\n);\r\n\r\nexport const StarIcon: React.FC<IconProps & { fill?: string }> = ({\r\n className,\r\n style,\r\n fill = \"none\",\r\n}) => (\r\n <svg\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 24 24\"\r\n fill={fill}\r\n stroke=\"currentColor\"\r\n strokeWidth=\"2\"\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n className={className}\r\n style={{ width: \"1em\", height: \"1em\", ...style }}\r\n >\r\n <polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\" />\r\n </svg>\r\n);\r\n","import React, { FunctionComponent, CSSProperties } from \"react\";\r\nimport { Chip } from \"./Chip\";\r\nimport { MinRatingFilterChip } from \"./MinRatingFilterChip\";\r\nimport { PriceRangeFilterChip } from \"./PriceRangeFilterChip\";\r\nimport { RestaurantPriceLevelChip } from \"./RestaurantPriceLevelChip\";\r\nimport { TransformedQueryChip } from \"./TransformedQueryChip\";\r\nimport { SearchIcon, NextIcon } from \"../Icons\";\r\nimport { useFilterScroll } from \"../../hooks/useFilterScroll\";\r\nimport { useTranslation } from \"../../hooks/useTranslation\";\r\nimport type { Filter } from \"./types\";\r\n\r\nexport interface FilterChipsProps {\r\n filters: Filter[];\r\n isPortrait: boolean;\r\n currency: string;\r\n minRatingSuffix: string;\r\n clearAllLabel: string;\r\n previousFiltersLabel: string;\r\n nextFiltersLabel: string;\r\n formatCurrency: (value: number, currency?: string) => string;\r\n onFilterChange: (\r\n filters: Filter[],\r\n clearAll?: boolean\r\n ) => void | Promise<void>;\r\n onResetFilters: () => void;\r\n onClearAll: () => void;\r\n}\r\n\r\nconst containerStyles: CSSProperties = {\r\n position: \"relative\",\r\n width: \"100%\",\r\n};\r\n\r\nconst scrollContainerBase: CSSProperties = {\r\n display: \"flex\",\r\n gap: \"8px\",\r\n overflowX: \"auto\",\r\n alignItems: \"center\",\r\n width: \"100%\",\r\n scrollbarWidth: \"none\",\r\n msOverflowStyle: \"none\",\r\n};\r\n\r\nconst gradientStyles: CSSProperties = {\r\n pointerEvents: \"none\",\r\n position: \"absolute\",\r\n top: 0,\r\n bottom: 0,\r\n width: \"40px\",\r\n};\r\n\r\nconst navButtonStyles: CSSProperties = {\r\n position: \"absolute\",\r\n top: \"50%\",\r\n transform: \"translateY(-50%)\",\r\n backgroundColor: \"white\",\r\n color: \"#003c30\",\r\n border: \"1px solid #003c30\",\r\n padding: \"4px\",\r\n borderRadius: \"50%\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n boxShadow: \"0 1px 3px rgba(0,0,0,0.1)\",\r\n cursor: \"pointer\",\r\n};\r\n\r\nexport const FilterChips: FunctionComponent<FilterChipsProps> = ({\r\n filters,\r\n isPortrait,\r\n currency,\r\n minRatingSuffix,\r\n clearAllLabel,\r\n previousFiltersLabel,\r\n nextFiltersLabel,\r\n formatCurrency,\r\n onFilterChange,\r\n onResetFilters,\r\n onClearAll,\r\n}) => {\r\n const { scrollerRef, atStart, atEnd, scrollByDir } = useFilterScroll(\r\n filters.length\r\n );\r\n const { t } = useTranslation();\r\n const [navHover, setNavHover] = React.useState<\"prev\" | \"next\" | null>(null);\r\n const [resetHover, setResetHover] = React.useState(false);\r\n const [clearHover, setClearHover] = React.useState(false);\r\n\r\n const scrollContainerStyles: CSSProperties = {\r\n ...scrollContainerBase,\r\n padding: isPortrait ? \"8px 16px\" : \"8px\",\r\n };\r\n\r\n return (\r\n <div style={containerStyles}>\r\n <div\r\n ref={scrollerRef}\r\n style={{\r\n ...scrollContainerStyles,\r\n // Hide scrollbar for webkit browsers\r\n WebkitOverflowScrolling: \"touch\",\r\n }}\r\n >\r\n <style>\r\n {`\r\n div::-webkit-scrollbar {\r\n display: none;\r\n }\r\n `}\r\n </style>\r\n <button\r\n style={{\r\n flexShrink: 0,\r\n backgroundColor: resetHover ? \"#03a03e\" : \"#03852e\",\r\n borderRadius: \"50%\",\r\n padding: \"8px\",\r\n cursor: \"pointer\",\r\n border: \"none\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n transition: \"background-color 0.2s\",\r\n }}\r\n onClick={onResetFilters}\r\n onMouseEnter={() => setResetHover(true)}\r\n onMouseLeave={() => setResetHover(false)}\r\n >\r\n <SearchIcon\r\n style={{ width: \"20px\", height: \"20px\", color: \"white\" }}\r\n />\r\n </button>\r\n {filters.map((filter) => {\r\n const renderStandardChip = () => (\r\n <Chip\r\n key={filter.id}\r\n label={filter.label}\r\n icon={filter.icon}\r\n remove={() => {\r\n void onFilterChange(filters.filter((f) => f.id !== filter.id));\r\n }}\r\n />\r\n );\r\n\r\n if (filter.type === \"minRating\") {\r\n const currentRating = filter.numericValue ?? Number(filter.value);\r\n if (!Number.isFinite(currentRating)) {\r\n return renderStandardChip();\r\n }\r\n\r\n return (\r\n <MinRatingFilterChip\r\n key={filter.id}\r\n rating={currentRating}\r\n onChange={(nextRating) => {\r\n const nextFilters = filters.map((f) =>\r\n f.id === filter.id\r\n ? {\r\n ...f,\r\n numericValue: nextRating,\r\n value: String(nextRating),\r\n }\r\n : f\r\n );\r\n void onFilterChange(nextFilters);\r\n }}\r\n onRemove={() =>\r\n void onFilterChange(filters.filter((f) => f.id !== filter.id))\r\n }\r\n />\r\n );\r\n }\r\n\r\n if (filter.type === \"starRating\") {\r\n const currentRating = filter.numericValue ?? Number(filter.value);\r\n if (!Number.isFinite(currentRating)) {\r\n return renderStandardChip();\r\n }\r\n\r\n return (\r\n <MinRatingFilterChip\r\n star\r\n key={filter.id}\r\n rating={currentRating}\r\n onChange={(nextRating) => {\r\n const nextFilters = filters.map((f) =>\r\n f.id === filter.id\r\n ? {\r\n ...f,\r\n numericValue: nextRating,\r\n value: String(nextRating),\r\n }\r\n : f\r\n );\r\n void onFilterChange(nextFilters);\r\n }}\r\n onRemove={() =>\r\n void onFilterChange(filters.filter((f) => f.id !== filter.id))\r\n }\r\n />\r\n );\r\n }\r\n\r\n if (filter.type === \"priceRange\" && filter.priceRange) {\r\n return (\r\n <PriceRangeFilterChip\r\n key={filter.id}\r\n priceRange={filter.priceRange}\r\n currency={currency}\r\n onChange={(nextRange) => {\r\n const nextFilters = filters.map((f) =>\r\n f.id === filter.id\r\n ? {\r\n ...f,\r\n priceRange: nextRange,\r\n }\r\n : f\r\n );\r\n void onFilterChange(nextFilters);\r\n }}\r\n onRemove={() =>\r\n void onFilterChange(filters.filter((f) => f.id !== filter.id))\r\n }\r\n />\r\n );\r\n }\r\n\r\n if (filter.type === \"transformed_query\") {\r\n return (\r\n <TransformedQueryChip\r\n key={filter.id}\r\n value={filter.value}\r\n onChange={(nextValue) => {\r\n const nextFilters = filters.map((f) =>\r\n f.id === filter.id\r\n ? {\r\n ...f,\r\n value: nextValue,\r\n }\r\n : f\r\n );\r\n void onFilterChange(nextFilters);\r\n }}\r\n onRemove={() =>\r\n void onFilterChange(filters.filter((f) => f.id !== filter.id))\r\n }\r\n />\r\n );\r\n }\r\n\r\n if (filter.type === \"selected_restaurant_price_levels\") {\r\n return (\r\n <RestaurantPriceLevelChip\r\n key={filter.id}\r\n values={filter.priceLevels ?? []}\r\n onChange={(nextLevels) => {\r\n const nextFilters = filters.map((f) =>\r\n f.id === filter.id\r\n ? {\r\n ...f,\r\n priceLevels: nextLevels,\r\n }\r\n : f\r\n );\r\n void onFilterChange(nextFilters);\r\n }}\r\n onRemove={() =>\r\n void onFilterChange(filters.filter((f) => f.id !== filter.id))\r\n }\r\n />\r\n );\r\n }\r\n\r\n return renderStandardChip();\r\n })}\r\n <button\r\n style={{\r\n flexShrink: 0,\r\n padding: \"4px 16px\",\r\n borderRadius: \"9999px\",\r\n cursor: \"pointer\",\r\n fontSize: \"14px\",\r\n userSelect: \"none\",\r\n border: \"none\",\r\n backgroundColor: clearHover ? \"#e5e5e5\" : \"transparent\",\r\n transition: \"background-color 0.2s\",\r\n }}\r\n onClick={onClearAll}\r\n onMouseEnter={() => setClearHover(true)}\r\n onMouseLeave={() => setClearHover(false)}\r\n >\r\n {clearAllLabel}\r\n </button>\r\n </div>\r\n\r\n {!atStart && (\r\n <div\r\n aria-hidden=\"true\"\r\n style={{\r\n ...gradientStyles,\r\n left: 0,\r\n background: \"linear-gradient(to right, white, transparent)\",\r\n }}\r\n />\r\n )}\r\n\r\n {!atEnd && (\r\n <div\r\n aria-hidden=\"true\"\r\n style={{\r\n ...gradientStyles,\r\n right: 0,\r\n background: \"linear-gradient(to left, white, transparent)\",\r\n }}\r\n />\r\n )}\r\n\r\n {!atStart && (\r\n <button\r\n type=\"button\"\r\n aria-label={previousFiltersLabel}\r\n style={{\r\n ...navButtonStyles,\r\n left: \"4px\",\r\n transform: \"translateY(-50%) rotate(180deg)\",\r\n backgroundColor: navHover === \"prev\" ? \"#e5e5e5\" : \"white\",\r\n }}\r\n onClick={() => scrollByDir(\"prev\")}\r\n onMouseEnter={() => setNavHover(\"prev\")}\r\n onMouseLeave={() => setNavHover(null)}\r\n >\r\n <NextIcon style={{ width: \"20px\", height: \"20px\" }} />\r\n </button>\r\n )}\r\n\r\n {!atEnd && (\r\n <button\r\n type=\"button\"\r\n aria-label={nextFiltersLabel}\r\n style={{\r\n ...navButtonStyles,\r\n right: \"4px\",\r\n backgroundColor: navHover === \"next\" ? \"#e5e5e5\" : \"white\",\r\n }}\r\n onClick={() => scrollByDir(\"next\")}\r\n onMouseEnter={() => setNavHover(\"next\")}\r\n onMouseLeave={() => setNavHover(null)}\r\n >\r\n <NextIcon style={{ width: \"20px\", height: \"20px\" }} />\r\n </button>\r\n )}\r\n </div>\r\n );\r\n};\r\n","import React, { CSSProperties, ReactNode } from \"react\";\r\nimport { CloseIcon } from \"../Icons\";\r\n\r\nexport interface ChipProps {\r\n label: string | ReactNode;\r\n icon?: ReactNode;\r\n remove: () => void;\r\n style?: CSSProperties;\r\n}\r\n\r\nconst chipStyles: CSSProperties = {\r\n position: \"relative\",\r\n backgroundColor: \"white\",\r\n color: \"black\",\r\n fontSize: \"14px\",\r\n borderRadius: \"9999px\",\r\n padding: \"0 16px\",\r\n paddingRight: \"20px\",\r\n border: \"1px solid #03852e\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: \"8px\",\r\n flexShrink: 0,\r\n height: \"34px\",\r\n};\r\n\r\nconst removeButtonStyles: CSSProperties = {\r\n position: \"absolute\",\r\n top: \"-8px\",\r\n right: \"-8px\",\r\n padding: \"2px\",\r\n borderRadius: \"50%\",\r\n backgroundColor: \"white\",\r\n border: \"1px solid #03852e\",\r\n cursor: \"pointer\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n transition: \"background-color 0.2s\",\r\n};\r\n\r\nconst iconStyles: CSSProperties = {\r\n width: \"17px\",\r\n height: \"17px\",\r\n};\r\n\r\nexport const Chip: React.FC<ChipProps> = ({ label, icon, remove, style }) => {\r\n const [isHovering, setIsHovering] = React.useState(false);\r\n\r\n return (\r\n <div style={{ ...chipStyles, ...style }}>\r\n {icon && (\r\n <span style={{ display: \"flex\", alignItems: \"center\" }}>{icon}</span>\r\n )}\r\n <span style={{ whiteSpace: \"nowrap\" }}>{label}</span>\r\n <button\r\n style={{\r\n ...removeButtonStyles,\r\n backgroundColor: isHovering ? \"#e5e5e5\" : \"white\",\r\n }}\r\n onClick={remove}\r\n onMouseEnter={() => setIsHovering(true)}\r\n onMouseLeave={() => setIsHovering(false)}\r\n aria-label=\"Remove filter\"\r\n >\r\n <CloseIcon style={iconStyles} />\r\n </button>\r\n </div>\r\n );\r\n};\r\n","import React, {\r\n FunctionComponent,\r\n useState,\r\n FocusEvent,\r\n CSSProperties,\r\n} from \"react\";\r\nimport { CloseIcon, StarIcon } from \"../Icons\";\r\nimport { useTranslation } from \"../../hooks/useTranslation\";\r\nimport { formatRatingValue } from \"./utils\";\r\n\r\nconst chipContainerStyles: CSSProperties = {\r\n position: \"relative\",\r\n backgroundColor: \"white\",\r\n color: \"black\",\r\n fontSize: \"14px\",\r\n borderRadius: \"9999px\",\r\n padding: \"0 16px\",\r\n paddingRight: \"20px\",\r\n border: \"1px solid #03852e\",\r\n display: \"flex\",\r\n gap: \"8px\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n flexShrink: 0,\r\n height: \"34px\",\r\n};\r\n\r\nconst removeButtonStyles: CSSProperties = {\r\n position: \"absolute\",\r\n top: \"-8px\",\r\n right: \"-8px\",\r\n padding: \"2px\",\r\n borderRadius: \"50%\",\r\n backgroundColor: \"white\",\r\n border: \"1px solid #03852e\",\r\n cursor: \"pointer\",\r\n transition: \"background-color 0.2s\",\r\n};\r\n\r\nconst starContainerStyles: CSSProperties = {\r\n display: \"flex\",\r\n gap: \"1px\",\r\n userSelect: \"none\",\r\n};\r\n\r\nconst circleBaseStyles: CSSProperties = {\r\n display: \"block\",\r\n width: \"12px\",\r\n height: \"12px\",\r\n borderRadius: \"50%\",\r\n border: \"1px solid #03852e\",\r\n pointerEvents: \"none\",\r\n};\r\n\r\nconst buttonBaseStyles: CSSProperties = {\r\n position: \"absolute\",\r\n top: 0,\r\n height: \"100%\",\r\n cursor: \"pointer\",\r\n backgroundColor: \"transparent\",\r\n border: \"none\",\r\n padding: 0,\r\n};\r\n\r\nexport const MinRatingFilterChip: FunctionComponent<{\r\n star?: boolean;\r\n rating: number;\r\n onChange: (rating: number) => void;\r\n onRemove: () => void;\r\n}> = ({ rating, onChange, onRemove, star = false }) => {\r\n const [hoverRating, setHoverRating] = useState<number | null>(null);\r\n const [removeHover, setRemoveHover] = useState(false);\r\n const { t } = useTranslation();\r\n\r\n const displayRating = hoverRating ?? rating;\r\n const formatLabel = (value: number) =>\r\n star && value\r\n ? value.toString()\r\n : t(\"smartFilter.minRating.label\", { value: formatRatingValue(value) });\r\n const removeLabel = t(\"smartFilter.minRating.remove\");\r\n const setLabel = (value: number) =>\r\n t(\"smartFilter.minRating.setTo\", { rating: formatRatingValue(value) });\r\n\r\n const getFillForStar = (index: number) => {\r\n const starNumber = index + 1;\r\n if (displayRating >= starNumber) {\r\n return \"full\" as const;\r\n }\r\n if (displayRating >= starNumber - 0.5) {\r\n return \"half\" as const;\r\n }\r\n return \"empty\" as const;\r\n };\r\n\r\n const handleSelect = (nextRating: number) => {\r\n setHoverRating(null);\r\n if (nextRating === rating) {\r\n return;\r\n }\r\n onChange(nextRating);\r\n };\r\n\r\n const handleBlur = (event: FocusEvent<HTMLButtonElement>) => {\r\n const related = event.relatedTarget as HTMLElement | null;\r\n if (\r\n !related ||\r\n !(event.currentTarget as HTMLElement)\r\n .closest(\"[data-min-rating-chip]\")\r\n ?.contains(related)\r\n ) {\r\n setHoverRating(null);\r\n }\r\n };\r\n\r\n return (\r\n <div style={chipContainerStyles} data-min-rating-chip>\r\n <div\r\n style={{ display: \"flex\", alignItems: \"center\", gap: \"4px\" }}\r\n onMouseLeave={() => setHoverRating(null)}\r\n >\r\n <div style={starContainerStyles}>\r\n {Array.from({ length: 5 }).map((_, index) => {\r\n const fillState = getFillForStar(index);\r\n const starNumber = index + 1;\r\n const halfValue = starNumber - 0.5;\r\n\r\n if (star) {\r\n return (\r\n <div\r\n key={index}\r\n style={{\r\n position: \"relative\",\r\n width: \"16px\",\r\n height: \"16px\",\r\n }}\r\n >\r\n <StarIcon\r\n fill={displayRating >= starNumber ? \"#03852e\" : \"none\"}\r\n style={{\r\n width: \"16px\",\r\n height: \"16px\",\r\n pointerEvents: \"none\",\r\n }}\r\n />\r\n <button\r\n type=\"button\"\r\n style={{\r\n ...buttonBaseStyles,\r\n left: 0,\r\n width: \"50%\",\r\n borderRadius: \"50% 0 0 50%\",\r\n }}\r\n onMouseEnter={() => setHoverRating(halfValue)}\r\n onFocus={() => setHoverRating(halfValue)}\r\n onBlur={handleBlur}\r\n onClick={() => handleSelect(halfValue)}\r\n aria-label={setLabel(halfValue)}\r\n title={formatLabel(halfValue)}\r\n />\r\n <button\r\n type=\"button\"\r\n style={{\r\n ...buttonBaseStyles,\r\n left: \"50%\",\r\n width: \"50%\",\r\n borderRadius: \"0 50% 50% 0\",\r\n }}\r\n onMouseEnter={() => setHoverRating(starNumber)}\r\n onFocus={() => setHoverRating(starNumber)}\r\n onBlur={handleBlur}\r\n onClick={() => handleSelect(starNumber)}\r\n aria-label={setLabel(starNumber)}\r\n title={formatLabel(starNumber)}\r\n />\r\n </div>\r\n );\r\n }\r\n\r\n const circleStyles: CSSProperties =\r\n fillState === \"full\"\r\n ? { ...circleBaseStyles, backgroundColor: \"#03852e\" }\r\n : circleBaseStyles;\r\n\r\n const halfCircleStyles: CSSProperties = {\r\n ...circleBaseStyles,\r\n background:\r\n \"linear-gradient(90deg, #03852e 50%, transparent 50%)\",\r\n };\r\n\r\n return (\r\n <div\r\n key={index}\r\n style={{ position: \"relative\", width: \"12px\", height: \"12px\" }}\r\n >\r\n <span\r\n style={fillState === \"half\" ? halfCircleStyles : circleStyles}\r\n />\r\n <button\r\n type=\"button\"\r\n style={{\r\n ...buttonBaseStyles,\r\n left: 0,\r\n width: \"50%\",\r\n borderRadius: \"50% 0 0 50%\",\r\n outline: \"2px solid transparent\",\r\n outlineOffset: \"1px\",\r\n }}\r\n onMouseEnter={() => setHoverRating(halfValue)}\r\n onFocus={() => setHoverRating(halfValue)}\r\n onBlur={handleBlur}\r\n onClick={() => handleSelect(halfValue)}\r\n aria-label={setLabel(halfValue)}\r\n title={formatLabel(halfValue)}\r\n />\r\n <button\r\n type=\"button\"\r\n style={{\r\n ...buttonBaseStyles,\r\n left: \"50%\",\r\n width: \"50%\",\r\n borderRadius: \"0 50% 50% 0\",\r\n outline: \"2px solid transparent\",\r\n outlineOffset: \"1px\",\r\n }}\r\n onMouseEnter={() => setHoverRating(starNumber)}\r\n onFocus={() => setHoverRating(starNumber)}\r\n onBlur={handleBlur}\r\n onClick={() => handleSelect(starNumber)}\r\n aria-label={setLabel(starNumber)}\r\n title={formatLabel(starNumber)}\r\n />\r\n </div>\r\n );\r\n })}\r\n </div>\r\n <span style={{ whiteSpace: \"nowrap\" }}>\r\n {formatLabel(displayRating)}\r\n </span>\r\n </div>\r\n <button\r\n style={{\r\n ...removeButtonStyles,\r\n backgroundColor: removeHover ? \"#e5e5e5\" : \"white\",\r\n }}\r\n onClick={onRemove}\r\n onMouseEnter={() => setRemoveHover(true)}\r\n onMouseLeave={() => setRemoveHover(false)}\r\n aria-label={removeLabel}\r\n title={removeLabel}\r\n >\r\n <CloseIcon style={{ width: \"17px\", height: \"17px\" }} />\r\n </button>\r\n </div>\r\n );\r\n};\r\n","import { useCallback, useState } from \"react\";\r\n\r\nexport type Locale = \"en\" | \"es\" | \"de\" | \"fr\" | \"it\" | \"pt\";\r\n\r\ntype TranslationFunction = (\r\n key: string,\r\n params?: Record<string, any>\r\n) => string;\r\ntype FormatCurrencyFunction = (value: number, currency?: string) => string;\r\n\r\nconst defaultTranslations: Record<string, string> = {\r\n \"smartFilter.placeholder\":\r\n \"Search for hotels, restaurants, or attractions...\",\r\n \"smartFilter.typingPrompt\": \"Type to search...\",\r\n \"smartFilter.nav.previous\": \"Previous filters\",\r\n \"smartFilter.nav.next\": \"Next filters\",\r\n \"smartFilter.toast.locationRequired\": \"Please select a location first\",\r\n \"smartFilter.clearAll\": \"Clear all\",\r\n \"smartFilter.minRating.suffix\": \"+\",\r\n \"smartFilter.minRating.label\": \"{{value}}+\",\r\n \"smartFilter.minRating.remove\": \"Remove rating filter\",\r\n \"smartFilter.minRating.setTo\": \"Set rating to {{rating}}\",\r\n \"smartFilter.priceRange.label\": \"Price Range\",\r\n \"smartFilter.priceRange.remove\": \"Remove price filter\",\r\n \"smartFilter.priceRange.edit\": \"Edit price\",\r\n \"smartFilter.transformedQuery.remove\": \"Remove search query\",\r\n \"smartFilter.transformedQuery.edit\": \"Edit search query\",\r\n \"smartFilter.restaurantPriceLevel.label\": \"Price Level\",\r\n \"smartFilter.restaurantPriceLevel.remove\": \"Remove price level filter\",\r\n \"smartFilter.restaurantPriceLevel.none\": \"Any\",\r\n \"smartFilter.restaurantPriceLevel.options.cheapEats\": \"Cheap Eats\",\r\n \"smartFilter.restaurantPriceLevel.options.midRange\": \"Mid Range\",\r\n \"smartFilter.restaurantPriceLevel.options.fineDining\": \"Fine Dining\",\r\n};\r\n\r\nconst formatCurrencyDefault: FormatCurrencyFunction = (\r\n value,\r\n currency = \"USD\"\r\n) => {\r\n return new Intl.NumberFormat(\"en-US\", {\r\n style: \"currency\",\r\n currency: currency,\r\n minimumFractionDigits: 0,\r\n maximumFractionDigits: 0,\r\n }).format(value);\r\n};\r\n\r\n/**\r\n * Simple translation hook with default English translations.\r\n * Can be extended with custom translations and locales.\r\n */\r\nexport const useTranslation = (\r\n customTranslations?: Record<string, string>,\r\n customFormatCurrency?: FormatCurrencyFunction\r\n) => {\r\n const [locale, setLocale] = useState<Locale>(\"en\");\r\n\r\n const t: TranslationFunction = useCallback(\r\n (key: string, params?: Record<string, any>) => {\r\n const translations = { ...defaultTranslations, ...customTranslations };\r\n let translation = translations[key] || key;\r\n\r\n if (params) {\r\n Object.keys(params).forEach((paramKey) => {\r\n translation = translation.replace(\r\n new RegExp(`{{${paramKey}}}`, \"g\"),\r\n String(params[paramKey])\r\n );\r\n });\r\n }\r\n\r\n return translation;\r\n },\r\n [customTranslations]\r\n );\r\n\r\n const formatCurrency = useCallback(\r\n (value: number, currency?: string) => {\r\n if (customFormatCurrency) {\r\n return customFormatCurrency(value, currency);\r\n }\r\n return formatCurrencyDefault(value, currency);\r\n },\r\n [customFormatCurrency]\r\n );\r\n\r\n return {\r\n t,\r\n locale,\r\n setLocale,\r\n formatCurrency,\r\n };\r\n};\r\n","import React, { ReactNode, CSSProperties } from \"react\";\r\n\r\nexport const renderStars = (rating: number): ReactNode[] => {\r\n const stars: ReactNode[] = [];\r\n const fullStars = Math.floor(rating);\r\n const hasHalfStar = rating % 1 !== 0;\r\n\r\n const baseStyles: CSSProperties = {\r\n display: \"block\",\r\n width: \"12px\",\r\n height: \"12px\",\r\n borderRadius: \"50%\",\r\n border: \"1px solid #03852e\",\r\n pointerEvents: \"none\",\r\n };\r\n\r\n const fullStarStyles: CSSProperties = {\r\n ...baseStyles,\r\n backgroundColor: \"#03852e\",\r\n };\r\n\r\n const halfStarStyles: CSSProperties = {\r\n ...baseStyles,\r\n background: \"linear-gradient(90deg, #03852e 50%, transparent 50%)\",\r\n };\r\n\r\n for (let i = 0; i < fullStars; i += 1) {\r\n stars.push(<span key={`full-${i}`} style={fullStarStyles} />);\r\n }\r\n\r\n if (hasHalfStar) {\r\n stars.push(<span key=\"half\" style={halfStarStyles} />);\r\n }\r\n\r\n const remainingStars = Math.max(0, 5 - Math.ceil(rating));\r\n for (let i = 0; i < remainingStars; i += 1) {\r\n stars.push(<span key={`empty-${i}`} style={baseStyles} />);\r\n }\r\n\r\n return stars;\r\n};\r\n\r\nexport const createMinRatingFilterLabel = (\r\n rating: number,\r\n suffix?: string\r\n): ReactNode => (\r\n <span style={{ display: \"flex\", alignItems: \"center\", gap: \"4px\" }}>\r\n <span\r\n style={{\r\n display: \"flex\",\r\n gap: \"1px\",\r\n userSelect: \"none\",\r\n }}\r\n >\r\n {renderStars(rating)}\r\n </span>{\" \"}\r\n {suffix}\r\n </span>\r\n);\r\n\r\nexport const formatRatingValue = (rating: number): string => rating.toFixed(1);\r\n\r\nexport const createPriceRangeFilterLabel = (\r\n min: number,\r\n max: number | undefined,\r\n currency: string | undefined,\r\n formatCurrencyFn: (value: number, currency?: string) => string\r\n): string =>\r\n `${formatCurrencyFn(min, currency)} - ${formatCurrencyFn(\r\n max ?? 0,\r\n currency\r\n )}`;\r\n","import React, {\r\n ChangeEvent,\r\n FunctionComponent,\r\n KeyboardEvent,\r\n useEffect,\r\n useState,\r\n CSSProperties,\r\n} from \"react\";\r\nimport { CloseIcon, EditIcon } from \"../Icons\";\r\nimport { useTranslation } from \"../../hooks/useTranslation\";\r\nimport type { PriceRangeValue } from \"./types\";\r\n\r\ntype Boundary = \"min\" | \"max\";\r\n\r\nconst chipStyles: CSSProperties = {\r\n position: \"relative\",\r\n backgroundColor: \"white\",\r\n color: \"black\",\r\n fontSize: \"14px\",\r\n borderRadius: \"9999px\",\r\n padding: \"0 16px\",\r\n border: \"1px solid #03852e\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: \"8px\",\r\n flexShrink: 0,\r\n height: \"34px\",\r\n};\r\n\r\nconst removeButtonStyles: CSSProperties = {\r\n position: \"absolute\",\r\n top: \"-8px\",\r\n right: \"-8px\",\r\n padding: \"2px\",\r\n borderRadius: \"50%\",\r\n backgroundColor: \"white\",\r\n border: \"1px solid #03852e\",\r\n cursor: \"pointer\",\r\n transition: \"background-color 0.2s\",\r\n};\r\n\r\nconst inputStyles: CSSProperties = {\r\n outline: \"none\",\r\n fontSize: \"16px\",\r\n backgroundColor: \"transparent\",\r\n borderRadius: \"2px\",\r\n padding: \"2px 8px\",\r\n width: \"64px\",\r\n textAlign: \"center\",\r\n border: \"none\",\r\n};\r\n\r\nconst editButtonStyles: CSSProperties = {\r\n padding: \"4px\",\r\n borderRadius: \"50%\",\r\n cursor: \"pointer\",\r\n transition: \"background-color 0.2s\",\r\n border: \"none\",\r\n backgroundColor: \"transparent\",\r\n color: \"#737373\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n};\r\n\r\ninterface PriceBoundaryChipProps {\r\n boundary: Boundary;\r\n label: string;\r\n value?: number;\r\n placeholder?: string;\r\n currency: string;\r\n isOptional?: boolean;\r\n showRemoveButton?: boolean;\r\n removeLabel?: string;\r\n editLabel?: string;\r\n showAddWhenEmpty?: boolean;\r\n onCommit: (value?: number) => void;\r\n onRemove: () => void;\r\n}\r\n\r\nconst PriceBoundaryChip: FunctionComponent<PriceBoundaryChipProps> = ({\r\n boundary,\r\n label,\r\n value,\r\n placeholder,\r\n currency,\r\n isOptional = false,\r\n showRemoveButton = false,\r\n removeLabel,\r\n editLabel,\r\n showAddWhenEmpty = false,\r\n onCommit,\r\n onRemove,\r\n}) => {\r\n const [draft, setDraft] = useState<string>(\r\n value !== undefined ? String(value) : \"\"\r\n );\r\n const [isEditing, setIsEditing] = useState(false);\r\n const [editHover, setEditHover] = useState(false);\r\n const [removeHover, setRemoveHover] = useState(false);\r\n const hasValue = value !== undefined;\r\n\r\n useEffect(() => {\r\n setDraft(value !== undefined ? String(value) : \"\");\r\n setIsEditing(false);\r\n }, [value]);\r\n\r\n const resetDraft = () => {\r\n setDraft(value !== undefined ? String(value) : \"\");\r\n };\r\n\r\n const commitValue = () => {\r\n if (draft.trim() === \"\") {\r\n if (isOptional) {\r\n onCommit(undefined);\r\n setDraft(\"\");\r\n return;\r\n }\r\n resetDraft();\r\n return;\r\n }\r\n\r\n const parsed = Number(draft);\r\n if (!Number.isFinite(parsed)) {\r\n resetDraft();\r\n return;\r\n }\r\n\r\n const normalized = Math.max(0, parsed);\r\n if (normalized === value) {\r\n resetDraft();\r\n return;\r\n }\r\n onCommit(normalized);\r\n };\r\n\r\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\r\n const next = event.target.value.replace(/[^\\d]/g, \"\");\r\n setDraft(next);\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\r\n if (event.key === \"Enter\") {\r\n event.preventDefault();\r\n (event.currentTarget as HTMLInputElement).blur();\r\n setIsEditing(false);\r\n return;\r\n }\r\n\r\n if (event.key === \"Escape\") {\r\n event.preventDefault();\r\n resetDraft();\r\n (event.currentTarget as HTMLInputElement).blur();\r\n setIsEditing(false);\r\n return;\r\n }\r\n\r\n const allowed =\r\n (event.key.length === 1 && /[0-9]/.test(event.key)) ||\r\n event.key === \"Backspace\" ||\r\n event.key === \"Delete\" ||\r\n event.key === \"Tab\" ||\r\n event.key === \"ArrowLeft\" ||\r\n event.key === \"ArrowRight\" ||\r\n event.key === \"Home\" ||\r\n event.key === \"End\";\r\n\r\n if (!allowed) {\r\n event.preventDefault();\r\n }\r\n };\r\n\r\n return (\r\n <div style={chipStyles}>\r\n <span\r\n style={{\r\n fontSize: \"10px\",\r\n textTransform: \"uppercase\",\r\n fontWeight: 600,\r\n letterSpacing: \"0.05em\",\r\n }}\r\n >\r\n {label}\r\n </span>\r\n {isEditing ? (\r\n <input\r\n value={draft}\r\n onChange={handleChange}\r\n onBlur={() => {\r\n commitValue();\r\n setIsEditing(false);\r\n }}\r\n onKeyDown={handleKeyDown}\r\n placeholder={placeholder}\r\n inputMode=\"numeric\"\r\n pattern=\"[0-9]*\"\r\n aria-label={label}\r\n style={inputStyles}\r\n autoFocus\r\n />\r\n ) : hasValue ? (\r\n <span style={{ fontSize: \"16px\" }}>\r\n {currency}\r\n {value}\r\n </span>\r\n ) : showAddWhenEmpty ? (\r\n <button\r\n type=\"button\"\r\n style={{\r\n fontSize: \"16px\",\r\n color: \"#737373\",\r\n cursor: \"pointer\",\r\n border: \"none\",\r\n backgroundColor: \"transparent\",\r\n padding: 0,\r\n }}\r\n onClick={() => setIsEditing(true)}\r\n aria-label={editLabel}\r\n >\r\n +\r\n </button>\r\n ) : (\r\n <span style={{ fontSize: \"16px\", color: \"#737373\" }}>-</span>\r\n )}\r\n {(!showAddWhenEmpty || (showAddWhenEmpty && isEditing)) && (\r\n <span style={{ color: \"#737373\", fontSize: \"12px\" }}>{currency}</span>\r\n )}\r\n {!isEditing && (!showAddWhenEmpty || hasValue) && (\r\n <button\r\n type=\"button\"\r\n style={{\r\n ...editButtonStyles,\r\n backgroundColor: editHover ? \"#e5e5e5\" : \"transparent\",\r\n }}\r\n aria-label={editLabel}\r\n title={editLabel}\r\n onClick={() => setIsEditing(true)}\r\n onMouseEnter={() => setEditHover(true)}\r\n onMouseLeave={() => setEditHover(false)}\r\n >\r\n <EditIcon />\r\n </button>\r\n )}\r\n {showRemoveButton && (\r\n <button\r\n style={{\r\n ...removeButtonStyles,\r\n backgroundColor: removeHover ? \"#e5e5e5\" : \"white\",\r\n }}\r\n onClick={onRemove}\r\n onMouseEnter={() => setRemoveHover(true)}\r\n onMouseLeave={() => setRemoveHover(false)}\r\n aria-label={removeLabel}\r\n title={removeLabel}\r\n >\r\n <CloseIcon style={{ width: \"17px\", height: \"17px\" }} />\r\n </button>\r\n )}\r\n </div>\r\n );\r\n};\r\n\r\nexport const PriceRangeFilterChip: FunctionComponent<{\r\n priceRange: PriceRangeValue;\r\n currency: string;\r\n onChange: (range: PriceRangeValue) => void;\r\n onRemove: () => void;\r\n}> = ({ priceRange, currency, onChange, onRemove }) => {\r\n const { t } = useTranslation();\r\n\r\n const minLabel = \"Min\";\r\n const maxChipLabel = \"Max\";\r\n const removeLabel = t(\"smartFilter.priceRange.remove\");\r\n const editLabel = t(\"smartFilter.priceRange.edit\");\r\n\r\n const handleBoundaryCommit = (boundary: Boundary, nextValue?: number) => {\r\n const nextRange: PriceRangeValue = {\r\n min: priceRange.min,\r\n max: priceRange.max,\r\n };\r\n\r\n if (boundary === \"min\") {\r\n nextRange.min = nextValue;\r\n if (\r\n nextValue !== undefined &&\r\n priceRange.max !== undefined &&\r\n nextValue > priceRange.max\r\n ) {\r\n nextRange.max = nextValue;\r\n }\r\n } else {\r\n nextRange.max = nextValue;\r\n if (\r\n nextValue !== undefined &&\r\n priceRange.min !== undefined &&\r\n nextValue < priceRange.min\r\n ) {\r\n nextRange.min = nextValue;\r\n }\r\n }\r\n\r\n if (nextRange.min !== priceRange.min || nextRange.max !== priceRange.max) {\r\n onChange(nextRange);\r\n }\r\n };\r\n\r\n return (\r\n <>\r\n <PriceBoundaryChip\r\n boundary=\"min\"\r\n label={minLabel}\r\n value={priceRange.min}\r\n currency={currency}\r\n editLabel={editLabel}\r\n showRemoveButton={priceRange.min !== undefined && priceRange.min !== 0}\r\n onCommit={(value) => handleBoundaryCommit(\"min\", value)}\r\n onRemove={onRemove}\r\n />\r\n <PriceBoundaryChip\r\n boundary=\"max\"\r\n label={maxChipLabel}\r\n value={priceRange.max}\r\n currency={currency}\r\n isOptional\r\n showRemoveButton={priceRange.max !== undefined}\r\n removeLabel={removeLabel}\r\n editLabel={editLabel}\r\n showAddWhenEmpty\r\n onCommit={(value) => handleBoundaryCommit(\"max\", value)}\r\n onRemove={onRemove}\r\n />\r\n </>\r\n );\r\n};\r\n","import React, { ChangeEvent, FunctionComponent, CSSProperties } from \"react\";\r\nimport { CloseIcon } from \"../Icons\";\r\nimport { useTranslation } from \"../../hooks/useTranslation\";\r\nimport type { PriceLevel } from \"@mapfirst.ai/core\";\r\n\r\nconst chipStyles: CSSProperties = {\r\n position: \"relative\",\r\n backgroundColor: \"white\",\r\n color: \"black\",\r\n fontSize: \"14px\",\r\n borderRadius: \"9999px\",\r\n padding: \"0 16px\",\r\n paddingRight: \"20px\",\r\n border: \"1px solid #03852e\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: \"16px\",\r\n flexShrink: 0,\r\n height: \"34px\",\r\n};\r\n\r\nconst removeButtonStyles: CSSProperties = {\r\n position: \"absolute\",\r\n top: \"-8px\",\r\n right: \"-8px\",\r\n padding: \"2px\",\r\n borderRadius: \"50%\",\r\n backgroundColor: \"white\",\r\n border: \"1px solid #03852e\",\r\n cursor: \"pointer\",\r\n transition: \"background-color 0.2s\",\r\n};\r\n\r\nconst PRICE_LEVEL_OPTIONS = [\r\n { value: \"Cheap Eats\" as PriceLevel, key: \"cheapEats\" },\r\n { value: \"Mid Range\" as PriceLevel, key: \"midRange\" },\r\n { value: \"Fine Dining\" as PriceLevel, key: \"fineDining\" },\r\n] as const;\r\n\r\nexport interface RestaurantPriceLevelChipProps {\r\n values: PriceLevel[];\r\n onChange: (values: PriceLevel[]) => void;\r\n onRemove: () => void;\r\n}\r\n\r\nexport const RestaurantPriceLevelChip: FunctionComponent<\r\n RestaurantPriceLevelChipProps\r\n> = ({ values, onChange, onRemove }) => {\r\n const { t } = useTranslation();\r\n const [removeHover, setRemoveHover] = React.useState(false);\r\n\r\n const label = t(\"smartFilter.restaurantPriceLevel.label\");\r\n const removeLabel = t(\"smartFilter.restaurantPriceLevel.remove\");\r\n const noneSelectedLabel = t(\"smartFilter.restaurantPriceLevel.none\");\r\n\r\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\r\n const { value, checked } = event.target;\r\n const valueAsPriceLevel = value as PriceLevel;\r\n const selection = new Set(values);\r\n if (checked) {\r\n selection.add(valueAsPriceLevel);\r\n } else {\r\n selection.delete(valueAsPriceLevel);\r\n }\r\n const orderedSelection = PRICE_LEVEL_OPTIONS.filter((option) =>\r\n selection.has(option.value)\r\n ).map((option) => option.value);\r\n onChange(orderedSelection);\r\n };\r\n\r\n return (\r\n <div style={chipStyles}>\r\n <div\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: \"8px\",\r\n flexWrap: \"wrap\",\r\n }}\r\n >\r\n <span\r\n style={{\r\n fontSize: \"10px\",\r\n textTransform: \"uppercase\",\r\n fontWeight: 600,\r\n letterSpacing: \"0.05em\",\r\n }}\r\n >\r\n {label}\r\n </span>\r\n <div style={{ display: \"flex\", gap: \"12px\" }}>\r\n {PRICE_LEVEL_OPTIONS.map((option) => {\r\n const optionLabel = t(\r\n `smartFilter.restaurantPriceLevel.options.${option.key}`\r\n );\r\n const checkboxId = `price-level-${option.key}`;\r\n return (\r\n <label\r\n key={option.value}\r\n htmlFor={checkboxId}\r\n style={{\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: \"4px\",\r\n fontSize: \"12px\",\r\n cursor: \"pointer\",\r\n }}\r\n >\r\n <input\r\n id={checkboxId}\r\n type=\"checkbox\"\r\n value={option.value}\r\n checked={values.includes(option.value)}\r\n onChange={handleChange}\r\n style={{ accentColor: \"#03852e\", cursor: \"pointer\" }}\r\n />\r\n <span>{optionLabel}</span>\r\n </label>\r\n );\r\n })}\r\n {values.length === 0 && (\r\n <span style={{ fontSize: \"12px\", color: \"#737373\" }}>\r\n {noneSelectedLabel}\r\n </span>\r\n )}\r\n </div>\r\n </div>\r\n\r\n <button\r\n style={{\r\n ...removeButtonStyles,\r\n backgroundColor: removeHover ? \"#e5e5e5\" : \"white\",\r\n }}\r\n onClick={onRemove}\r\n onMouseEnter={() => setRemoveHover(true)}\r\n onMouseLeave={() => setRemoveHover(false)}\r\n aria-label={removeLabel ?? label}\r\n title={removeLabel ?? label}\r\n >\r\n <CloseIcon style={{ width: \"17px\", height: \"17px\" }} />\r\n </button>\r\n </div>\r\n );\r\n};\r\n","import React, {\r\n ChangeEvent,\r\n FunctionComponent,\r\n KeyboardEvent,\r\n useEffect,\r\n useRef,\r\n useState,\r\n CSSProperties,\r\n} from \"react\";\r\nimport { CloseIcon, EditIcon, SearchIcon } from \"../Icons\";\r\nimport { useTranslation } from \"../../hooks/useTranslation\";\r\n\r\nconst chipStyles: CSSProperties = {\r\n position: \"relative\",\r\n backgroundColor: \"white\",\r\n color: \"black\",\r\n fontSize: \"14px\",\r\n borderRadius: \"9999px\",\r\n padding: \"0 16px\",\r\n paddingRight: \"20px\",\r\n border: \"1px solid #03852e\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n gap: \"8px\",\r\n flexShrink: 0,\r\n userSelect: \"none\",\r\n height: \"34px\",\r\n};\r\n\r\nconst removeButtonStyles: CSSProperties = {\r\n position: \"absolute\",\r\n top: \"-8px\",\r\n right: \"-8px\",\r\n padding: \"2px\",\r\n borderRadius: \"50%\",\r\n backgroundColor: \"white\",\r\n border: \"1px solid #03852e\",\r\n cursor: \"pointer\",\r\n transition: \"background-color 0.2s\",\r\n};\r\n\r\nconst inputStyles: CSSProperties = {\r\n backgroundColor: \"#ececec\",\r\n borderRadius: \"2px\",\r\n padding: \"2px 8px\",\r\n outline: \"none\",\r\n fontSize: \"16px\",\r\n minWidth: \"8ch\",\r\n border: \"none\",\r\n};\r\n\r\nconst editButtonStyles: CSSProperties = {\r\n padding: \"4px\",\r\n borderRadius: \"50%\",\r\n cursor: \"pointer\",\r\n transition: \"background-color 0.2s\",\r\n color: \"#737373\",\r\n border: \"none\",\r\n backgroundColor: \"transparent\",\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n};\r\n\r\nexport interface TransformedQueryChipProps {\r\n value: string;\r\n onChange: (nextValue: string) => void;\r\n onRemove: () => void;\r\n}\r\n\r\nexport const TransformedQueryChip: FunctionComponent<\r\n TransformedQueryChipProps\r\n> = ({ value, onChange, onRemove }) => {\r\n const inputRef = useRef<HTMLInputElement | null>(null);\r\n const [draft, setDraft] = useState(value);\r\n const [isEditing, setIsEditing] = useState(false);\r\n const [editHover, setEditHover] = useState(false);\r\n const [removeHover, setRemoveHover] = useState(false);\r\n const { t } = useTranslation();\r\n\r\n const removeLabel = t(\"smartFilter.transformedQuery.remove\");\r\n const editLabel = t(\"smartFilter.transformedQuery.edit\");\r\n\r\n useEffect(() => {\r\n setDraft(value);\r\n setIsEditing(false);\r\n }, [value]);\r\n\r\n const applyChanges = () => {\r\n const nextValue = draft.trim();\r\n if (!nextValue.length) {\r\n setDraft(value);\r\n return;\r\n }\r\n if (nextValue === value) {\r\n return;\r\n }\r\n onChange(nextValue);\r\n };\r\n\r\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\r\n setDraft(event.target.value);\r\n };\r\n\r\n const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\r\n if (event.key === \"Enter\") {\r\n event.preventDefault();\r\n (event.currentTarget as HTMLInputElement).blur();\r\n return;\r\n }\r\n\r\n if (event.key === \"Escape\") {\r\n event.preventDefault();\r\n setDraft(value);\r\n (event.currentTarget as HTMLInputElement).blur();\r\n return;\r\n }\r\n };\r\n\r\n return (\r\n <div style={chipStyles}>\r\n <SearchIcon style={{ width: \"16px\", height: \"16px\", color: \"#03852e\" }} />\r\n {isEditing ? (\r\n <input\r\n ref={inputRef}\r\n value={draft}\r\n onChange={handleChange}\r\n onBlur={() => {\r\n applyChanges();\r\n setIsEditing(false);\r\n }}\r\n onKeyDown={handleKeyDown}\r\n aria-label={editLabel}\r\n style={inputStyles}\r\n autoFocus\r\n />\r\n ) : (\r\n <span style={{ fontSize: \"16px\" }}>{value}</span>\r\n )}\r\n {!isEditing && (\r\n <button\r\n type=\"button\"\r\n style={{\r\n ...editButtonStyles,\r\n backgroundColor: editHover ? \"#e5e5e5\" : \"transparent\",\r\n }}\r\n aria-label={editLabel}\r\n title={editLabel}\r\n onClick={() => setIsEditing(true)}\r\n onMouseEnter={() => setEditHover(true)}\r\n onMouseLeave={() => setEditHover(false)}\r\n >\r\n <EditIcon />\r\n </button>\r\n )}\r\n <button\r\n style={{\r\n ...removeButtonStyles,\r\n backgroundColor: removeHover ? \"#e5e5e5\" : \"white\",\r\n }}\r\n onClick={onRemove}\r\n onMouseEnter={() => setRemoveHover(true)}\r\n onMouseLeave={() => setRemoveHover(false)}\r\n aria-label={removeLabel}\r\n title={removeLabel}\r\n >\r\n <CloseIcon style={{ width: \"17px\", height: \"17px\" }} />\r\n </button>\r\n </div>\r\n );\r\n};\r\n","import { useCallback, useEffect, useRef, useState } from \"react\";\r\n\r\nexport const useFilterScroll = (dependency: number) => {\r\n const scrollerRef = useRef<HTMLDivElement | null>(null);\r\n const [atStart, setAtStart] = useState(true);\r\n const [atEnd, setAtEnd] = useState(true);\r\n\r\n const updateScrollButtons = useCallback(() => {\r\n const el = scrollerRef.current;\r\n if (!el) {\r\n setAtStart(true);\r\n setAtEnd(true);\r\n return;\r\n }\r\n\r\n const { scrollLeft, scrollWidth, clientWidth } = el;\r\n setAtStart(scrollLeft <= 0);\r\n setAtEnd(scrollLeft + clientWidth >= scrollWidth - 1);\r\n }, []);\r\n\r\n useEffect(() => {\r\n const el = scrollerRef.current;\r\n updateScrollButtons();\r\n if (!el) {\r\n return;\r\n }\r\n\r\n const handleScroll = () => updateScrollButtons();\r\n el.addEventListener(\"scroll\", handleScroll, { passive: true });\r\n window.addEventListener(\"resize\", updateScrollButtons);\r\n\r\n return () => {\r\n el.removeEventListener(\"scroll\", handleScroll);\r\n window.removeEventListener(\"resize\", updateScrollButtons);\r\n };\r\n }, [dependency, updateScrollButtons]);\r\n\r\n const scrollByDir = useCallback((dir: \"prev\" | \"next\") => {\r\n const el = scrollerRef.current;\r\n if (!el) {\r\n return;\r\n }\r\n\r\n const delta = el.clientWidth * 0.7;\r\n el.scrollBy({\r\n left: dir === \"next\" ? delta : -delta,\r\n behavior: \"smooth\",\r\n });\r\n }, []);\r\n\r\n return {\r\n scrollerRef,\r\n atStart,\r\n atEnd,\r\n scrollByDir,\r\n };\r\n};\r\n","import { useEffect, useState } from \"react\";\r\n\r\n/**\r\n * Hook to detect if the viewport is in portrait orientation.\r\n * Updates on window resize.\r\n */\r\nexport const useIsPortrait = (): boolean => {\r\n const [isPortrait, setIsPortrait] = useState(\r\n typeof window !== \"undefined\"\r\n ? window.innerHeight > window.innerWidth\r\n : false\r\n );\r\n\r\n useEffect(() => {\r\n if (typeof window === \"undefined\") {\r\n return;\r\n }\r\n\r\n const handleResize = () => {\r\n setIsPortrait(window.innerHeight > window.innerWidth);\r\n };\r\n\r\n window.addEventListener(\"resize\", handleResize);\r\n return () => window.removeEventListener(\"resize\", handleResize);\r\n }, []);\r\n\r\n return isPortrait;\r\n};\r\n"],"mappings":"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","names":["index_exports","__export","AiIcon","Chip","CloseIcon","EditIcon","FilterChips","MarkerDebugList","MinRatingFilterChip","NextIcon","PriceRangeFilterChip","RestaurantPriceLevelChip","SearchIcon","SmartFilter","StarIcon","TransformedQueryChip","createMinRatingFilterLabel","createPriceRangeFilterLabel","formatRatingValue","renderStars","useFilterScroll","useGoogleMapsAttachment","useIsPortrait","useMapFirst","useMapFirstCore","useMapFirstProperties","useMapFirstSelectedProperty","useMapLibreAttachment","useMapboxAttachment","usePrimaryType","usePropertiesSearch","useSelectedMarker","useSmartFilterSearch","useTranslation","__toCommonJS","import_react","import_core","import_react","import_jsx_runtime","SearchIcon","className","style","CloseIcon","EditIcon","NextIcon","AiIcon","StarIcon","fill","import_react","import_react","import_jsx_runtime","chipStyles","removeButtonStyles","iconStyles","Chip","label","icon","remove","style","isHovering","setIsHovering","React","CloseIcon","import_react","import_react","defaultTranslations","formatCurrencyDefault","value","currency","useTranslation","customTranslations","customFormatCurrency","locale","setLocale","t","key","params","translation","paramKey","formatCurrency","import_jsx_runtime","renderStars","rating","stars","fullStars","hasHalfStar","baseStyles","fullStarStyles","halfStarStyles","i","remainingStars","createMinRatingFilterLabel","suffix","formatRatingValue","createPriceRangeFilterLabel","min","max","currency","formatCurrencyFn","import_jsx_runtime","chipContainerStyles","removeButtonStyles","starContainerStyles","circleBaseStyles","buttonBaseStyles","MinRatingFilterChip","rating","onChange","onRemove","star","hoverRating","setHoverRating","removeHover","setRemoveHover","t","useTranslation","displayRating","formatLabel","value","formatRatingValue","removeLabel","setLabel","getFillForStar","index","starNumber","handleSelect","nextRating","handleBlur","event","_a","related","_","fillState","halfValue","StarIcon","circleStyles","halfCircleStyles","CloseIcon","import_react","import_jsx_runtime","chipStyles","removeButtonStyles","inputStyles","editButtonStyles","PriceBoundaryChip","boundary","label","value","placeholder","currency","isOptional","showRemoveButton","removeLabel","editLabel","showAddWhenEmpty","onCommit","onRemove","draft","setDraft","isEditing","setIsEditing","editHover","setEditHover","removeHover","setRemoveHover","hasValue","resetDraft","commitValue","parsed","normalized","event","next","EditIcon","CloseIcon","PriceRangeFilterChip","priceRange","onChange","t","useTranslation","minLabel","maxChipLabel","handleBoundaryCommit","nextValue","nextRange","import_react","import_jsx_runtime","chipStyles","removeButtonStyles","PRICE_LEVEL_OPTIONS","RestaurantPriceLevelChip","values","onChange","onRemove","t","useTranslation","removeHover","setRemoveHover","React","label","removeLabel","noneSelectedLabel","handleChange","event","value","checked","valueAsPriceLevel","selection","orderedSelection","option","optionLabel","checkboxId","CloseIcon","import_react","import_jsx_runtime","chipStyles","removeButtonStyles","inputStyles","editButtonStyles","TransformedQueryChip","value","onChange","onRemove","inputRef","draft","setDraft","isEditing","setIsEditing","editHover","setEditHover","removeHover","setRemoveHover","t","useTranslation","removeLabel","editLabel","applyChanges","nextValue","SearchIcon","event","EditIcon","CloseIcon","import_react","useFilterScroll","dependency","scrollerRef","atStart","setAtStart","atEnd","setAtEnd","updateScrollButtons","el","scrollLeft","scrollWidth","clientWidth","handleScroll","scrollByDir","dir","delta","import_jsx_runtime","containerStyles","scrollContainerBase","gradientStyles","navButtonStyles","FilterChips","filters","isPortrait","currency","minRatingSuffix","clearAllLabel","previousFiltersLabel","nextFiltersLabel","formatCurrency","onFilterChange","onResetFilters","onClearAll","scrollerRef","atStart","atEnd","scrollByDir","useFilterScroll","t","useTranslation","navHover","setNavHover","React","resetHover","setResetHover","clearHover","setClearHover","scrollContainerStyles","SearchIcon","filter","_a","_b","_c","renderStandardChip","Chip","f","currentRating","MinRatingFilterChip","nextRating","nextFilters","PriceRangeFilterChip","nextRange","TransformedQueryChip","nextValue","RestaurantPriceLevelChip","nextLevels","NextIcon","import_react","useIsPortrait","isPortrait","setIsPortrait","handleResize","import_jsx_runtime","containerStyles","formStyles","inputContainerStyles","iconStyles","inputStyles","loaderContainerStyles","loaderStyles","typingPromptStyles","SmartFilter","mapFirst","filters","controlledValue","isSearching","placeholder","onSearch","onFilterChange","onValueChange","showTypingPrompt","customTranslations","currency","style","inputStyle","containerStyle","internalValue","setInternalValue","value","setValue","isPortrait","useIsPortrait","t","formatCurrency","useTranslation","minRatingSuffix","placeholderText","typingPrompt","previousFiltersLabel","nextFiltersLabel","clearAllLabel","formSubmit","e","query","error","handleFilterChange","nextFilters","clearAll","resetFilters","clearAllFilters","AiIcon","FilterChips","import_jsx_runtime","useMapFirstCore","options","instanceRef","React","state","setState","optionsRef","opts","coreOptions","properties","_a","_b","prev","id","type","filters","bounds","center","zoom","location","loading","searching","instance","useMapFirstProperties","mapFirst","setProperties","useMapFirstSelectedProperty","selectedId","setSelectedId","usePrimaryType","primaryType","setPrimaryTypeState","setPrimaryType","useSelectedMarker","selectedMarker","setSelectedMarkerState","setSelectedMarker","useMapLibreAttachment","map","maplibregl","onMarkerClick","attachedRef","useGoogleMapsAttachment","google","useMapboxAttachment","mapboxgl","useMapFirst","usePropertiesSearch","isLoading","setIsLoading","error","setError","err","useSmartFilterSearch","MarkerDebugList","markers","marker","_c","_d","_e","_f"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,11 @@
1
- import c from"react";import{MapFirstCore as b}from"@mapfirst.ai/core";import{jsx as g,jsxs as d}from"react/jsx-runtime";function h(r){let a=c.useRef(null),[o,l]=c.useState(null),n=c.useRef(r);return c.useEffect(()=>{n.current=r}),c.useEffect(()=>{let y=n.current,p={adapter:null,...y,callbacks:{...y.callbacks,onPropertiesChange:t=>{var e,s;l(u=>u?{...u,properties:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onPropertiesChange)==null||s.call(e,t)},onSelectedPropertyChange:t=>{var e,s;l(u=>u?{...u,selectedPropertyId:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onSelectedPropertyChange)==null||s.call(e,t)},onPrimaryTypeChange:t=>{var e,s;l(u=>u?{...u,primary:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onPrimaryTypeChange)==null||s.call(e,t)},onFiltersChange:t=>{var e,s;l(u=>u?{...u,filters:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onFiltersChange)==null||s.call(e,t)},onBoundsChange:t=>{var e,s;l(u=>u?{...u,bounds:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onBoundsChange)==null||s.call(e,t)},onCenterChange:(t,e)=>{var s,u;l(f=>f?{...f,center:t,zoom:e}:null),(u=(s=n.current.callbacks)==null?void 0:s.onCenterChange)==null||u.call(s,t,e)},onZoomChange:t=>{var e,s;l(u=>u?{...u,zoom:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onZoomChange)==null||s.call(e,t)},onActiveLocationChange:t=>{var e,s;l(u=>u?{...u,activeLocation:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onActiveLocationChange)==null||s.call(e,t)},onLoadingStateChange:t=>{var e,s;l(u=>u?{...u,initialLoading:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onLoadingStateChange)==null||s.call(e,t)},onSearchingStateChange:t=>{var e,s;l(u=>u?{...u,isSearching:t}:null),(s=(e=n.current.callbacks)==null?void 0:e.onSearchingStateChange)==null||s.call(e,t)}}},i=new b(p);return a.current=i,l(i.getState()),()=>{i.destroy(),a.current=null,l(null)}},[]),{mapFirst:a.current,state:o}}function M(r){let[a,o]=c.useState([]);return c.useEffect(()=>{if(!r){o([]);return}o(r.getState().properties)},[r]),a}function C(r){let[a,o]=c.useState(null);return c.useEffect(()=>{if(!r){o(null);return}o(r.getState().selectedPropertyId)},[r]),a}function P(r){let[a,o]=c.useState("Accommodation");c.useEffect(()=>{if(!r){o("Accommodation");return}o(r.getState().primary)},[r]);let l=c.useCallback(n=>{r&&(r.setPrimaryType(n),o(n))},[r]);return[a,l]}function E(r){let[a,o]=c.useState(null);c.useEffect(()=>{if(!r){o(null);return}o(r.getState().selectedPropertyId)},[r]);let l=c.useCallback(n=>{r&&r.setSelectedMarker(n)},[r]);return[a,l]}function k({mapFirst:r,map:a,maplibregl:o,onMarkerClick:l}){let n=c.useRef(!1);c.useEffect(()=>{!r||!a||n.current||(r.attachMap(a,{platform:"maplibre",maplibregl:o,onMarkerClick:l}),n.current=!0)},[r,a,o,l])}function R({mapFirst:r,map:a,google:o,onMarkerClick:l}){let n=c.useRef(!1);c.useEffect(()=>{!r||!a||n.current||(r.attachMap(a,{platform:"google",google:o,onMarkerClick:l}),n.current=!0)},[r,a,o,l])}function x({mapFirst:r,map:a,mapboxgl:o,onMarkerClick:l}){let n=c.useRef(!1);c.useEffect(()=>{!r||!a||n.current||(r.attachMap(a,{platform:"mapbox",mapboxgl:o,onMarkerClick:l}),n.current=!0)},[r,a,o,l])}function F(r){let a=c.useRef(null);return c.useEffect(()=>{if(!r)return;let o=new b(r);return a.current=o,()=>{o.destroy(),a.current=null}},[r]),a}function w(r){let[a,o]=c.useState(!1),[l,n]=c.useState(null);return{search:c.useCallback(async p=>{if(!r){let i=new Error("MapFirst instance not available");throw n(i),i}o(!0),n(null);try{return await r.runPropertiesSearch({...p,onError:t=>{let e=t instanceof Error?t:new Error(String(t));n(e)}})}catch(i){let t=i instanceof Error?i:new Error(String(i));throw n(t),t}finally{o(!1)}},[r]),isLoading:a,error:l}}function L(r){let[a,o]=c.useState(!1),[l,n]=c.useState(null);return{search:c.useCallback(async p=>{if(!r){let i=new Error("MapFirst instance not available");throw n(i),i}o(!0),n(null);try{return await r.runSmartFilterSearch({...p,onError:t=>{let e=t instanceof Error?t:new Error(String(t));n(e)}})}catch(i){let t=i instanceof Error?i:new Error(String(i));throw n(t),t}finally{o(!1)}},[r]),isLoading:a,error:l}}function T({markers:r}){return d("div",{style:{fontFamily:"sans-serif",fontSize:14},children:[g("strong",{children:"Markers"}),g("ul",{children:r.map(a=>{var o,l,n,y,p,i;return d("li",{children:[a.name," \u2014 ",(n=(l=(o=a.location)==null?void 0:o.lat)==null?void 0:l.toFixed(3))!=null?n:"n/a",","," ",(i=(p=(y=a.location)==null?void 0:y.lon)==null?void 0:p.toFixed(3))!=null?i:"n/a"]},String(a.tripadvisor_id))})})]})}export{T as MarkerDebugList,R as useGoogleMapsAttachment,F as useMapFirst,h as useMapFirstCore,M as useMapFirstProperties,C as useMapFirstSelectedProperty,k as useMapLibreAttachment,x as useMapboxAttachment,P as usePrimaryType,w as usePropertiesSearch,E as useSelectedMarker,L as useSmartFilterSearch};
1
+ import g from"react";import{MapFirstCore as Le}from"@mapfirst.ai/core";import{useCallback as me,useState as pt}from"react";import{jsx as E,jsxs as Q}from"react/jsx-runtime";var V=({className:e,style:t})=>Q("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:[E("circle",{cx:"11",cy:"11",r:"8"}),E("path",{d:"m21 21-4.35-4.35"})]}),H=({className:e,style:t})=>Q("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:[E("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),E("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]}),q=({className:e,style:t})=>Q("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:[E("path",{d:"M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"}),E("path",{d:"M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"})]}),te=({className:e,style:t})=>E("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:E("polyline",{points:"9 18 15 12 9 6"})}),ge=({className:e,style:t})=>Q("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:[E("path",{d:"M12 2L2 7l10 5 10-5-10-5z"}),E("path",{d:"M2 17l10 5 10-5"}),E("path",{d:"M2 12l10 5 10-5"})]}),fe=({className:e,style:t,fill:o="none"})=>E("svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:o,stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",className:e,style:{width:"1em",height:"1em",...t},children:E("polygon",{points:"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"})});import pe from"react";import Ee from"react";import{jsx as K,jsxs as Be}from"react/jsx-runtime";var Me={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",paddingRight:"20px",border:"1px solid #03852e",display:"flex",alignItems:"center",gap:"8px",flexShrink:0,height:"34px"},Ie={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},Te={width:"17px",height:"17px"},re=({label:e,icon:t,remove:o,style:a})=>{let[i,p]=Ee.useState(!1);return Be("div",{style:{...Me,...a},children:[t&&K("span",{style:{display:"flex",alignItems:"center"},children:t}),K("span",{style:{whiteSpace:"nowrap"},children:e}),K("button",{style:{...Ie,backgroundColor:i?"#e5e5e5":"white"},onClick:o,onMouseEnter:()=>p(!0),onMouseLeave:()=>p(!1),"aria-label":"Remove filter",children:K(H,{style:Te})})]})};import{useState as he}from"react";import{useCallback as ye,useState as He}from"react";var Ne={"smartFilter.placeholder":"Search for hotels, restaurants, or attractions...","smartFilter.typingPrompt":"Type to search...","smartFilter.nav.previous":"Previous filters","smartFilter.nav.next":"Next filters","smartFilter.toast.locationRequired":"Please select a location first","smartFilter.clearAll":"Clear all","smartFilter.minRating.suffix":"+","smartFilter.minRating.label":"{{value}}+","smartFilter.minRating.remove":"Remove rating filter","smartFilter.minRating.setTo":"Set rating to {{rating}}","smartFilter.priceRange.label":"Price Range","smartFilter.priceRange.remove":"Remove price filter","smartFilter.priceRange.edit":"Edit price","smartFilter.transformedQuery.remove":"Remove search query","smartFilter.transformedQuery.edit":"Edit search query","smartFilter.restaurantPriceLevel.label":"Price Level","smartFilter.restaurantPriceLevel.remove":"Remove price level filter","smartFilter.restaurantPriceLevel.none":"Any","smartFilter.restaurantPriceLevel.options.cheapEats":"Cheap Eats","smartFilter.restaurantPriceLevel.options.midRange":"Mid Range","smartFilter.restaurantPriceLevel.options.fineDining":"Fine Dining"},De=(e,t="USD")=>new Intl.NumberFormat("en-US",{style:"currency",currency:t,minimumFractionDigits:0,maximumFractionDigits:0}).format(e),M=(e,t)=>{let[o,a]=He("en"),i=ye((u,c)=>{let n={...Ne,...e}[u]||u;return c&&Object.keys(c).forEach(s=>{n=n.replace(new RegExp(`{{${s}}}`,"g"),String(c[s]))}),n},[e]),p=ye((u,c)=>t?t(u,c):De(u,c),[t]);return{t:i,locale:o,setLocale:a,formatCurrency:p}};import{jsx as $,jsxs as ze}from"react/jsx-runtime";var Ae=e=>{let t=[],o=Math.floor(e),a=e%1!==0,i={display:"block",width:"12px",height:"12px",borderRadius:"50%",border:"1px solid #03852e",pointerEvents:"none"},p={...i,backgroundColor:"#03852e"},u={...i,background:"linear-gradient(90deg, #03852e 50%, transparent 50%)"};for(let r=0;r<o;r+=1)t.push($("span",{style:p},`full-${r}`));a&&t.push($("span",{style:u},"half"));let c=Math.max(0,5-Math.ceil(e));for(let r=0;r<c;r+=1)t.push($("span",{style:i},`empty-${r}`));return t},Mt=(e,t)=>ze("span",{style:{display:"flex",alignItems:"center",gap:"4px"},children:[$("span",{style:{display:"flex",gap:"1px",userSelect:"none"},children:Ae(e)})," ",t]}),ne=e=>e.toFixed(1),It=(e,t,o,a)=>`${a(e,o)} - ${a(t!=null?t:0,o)}`;import{jsx as N,jsxs as j}from"react/jsx-runtime";var We={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",paddingRight:"20px",border:"1px solid #03852e",display:"flex",gap:"8px",alignItems:"center",justifyContent:"center",flexShrink:0,height:"34px"},Oe={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",transition:"background-color 0.2s"},_e={display:"flex",gap:"1px",userSelect:"none"},oe={display:"block",width:"12px",height:"12px",borderRadius:"50%",border:"1px solid #03852e",pointerEvents:"none"},Y={position:"absolute",top:0,height:"100%",cursor:"pointer",backgroundColor:"transparent",border:"none",padding:0},G=({rating:e,onChange:t,onRemove:o,star:a=!1})=>{let[i,p]=he(null),[u,c]=he(!1),{t:r}=M(),n=i!=null?i:e,s=f=>a&&f?f.toString():r("smartFilter.minRating.label",{value:ne(f)}),l=r("smartFilter.minRating.remove"),m=f=>r("smartFilter.minRating.setTo",{rating:ne(f)}),P=f=>{let S=f+1;return n>=S?"full":n>=S-.5?"half":"empty"},v=f=>{p(null),f!==e&&t(f)},C=f=>{var x;let S=f.relatedTarget;(!S||!((x=f.currentTarget.closest("[data-min-rating-chip]"))!=null&&x.contains(S)))&&p(null)};return j("div",{style:We,"data-min-rating-chip":!0,children:[j("div",{style:{display:"flex",alignItems:"center",gap:"4px"},onMouseLeave:()=>p(null),children:[N("div",{style:_e,children:Array.from({length:5}).map((f,S)=>{let x=P(S),h=S+1,k=h-.5;if(a)return j("div",{style:{position:"relative",width:"16px",height:"16px"},children:[N(fe,{fill:n>=h?"#03852e":"none",style:{width:"16px",height:"16px",pointerEvents:"none"}}),N("button",{type:"button",style:{...Y,left:0,width:"50%",borderRadius:"50% 0 0 50%"},onMouseEnter:()=>p(k),onFocus:()=>p(k),onBlur:C,onClick:()=>v(k),"aria-label":m(k),title:s(k)}),N("button",{type:"button",style:{...Y,left:"50%",width:"50%",borderRadius:"0 50% 50% 0"},onMouseEnter:()=>p(h),onFocus:()=>p(h),onBlur:C,onClick:()=>v(h),"aria-label":m(h),title:s(h)})]},S);let I=x==="full"?{...oe,backgroundColor:"#03852e"}:oe,A={...oe,background:"linear-gradient(90deg, #03852e 50%, transparent 50%)"};return j("div",{style:{position:"relative",width:"12px",height:"12px"},children:[N("span",{style:x==="half"?A:I}),N("button",{type:"button",style:{...Y,left:0,width:"50%",borderRadius:"50% 0 0 50%",outline:"2px solid transparent",outlineOffset:"1px"},onMouseEnter:()=>p(k),onFocus:()=>p(k),onBlur:C,onClick:()=>v(k),"aria-label":m(k),title:s(k)}),N("button",{type:"button",style:{...Y,left:"50%",width:"50%",borderRadius:"0 50% 50% 0",outline:"2px solid transparent",outlineOffset:"1px"},onMouseEnter:()=>p(h),onFocus:()=>p(h),onBlur:C,onClick:()=>v(h),"aria-label":m(h),title:s(h)})]},S)})}),N("span",{style:{whiteSpace:"nowrap"},children:s(n)})]}),N("button",{style:{...Oe,backgroundColor:u?"#e5e5e5":"white"},onClick:o,onMouseEnter:()=>c(!0),onMouseLeave:()=>c(!1),"aria-label":l,title:l,children:N(H,{style:{width:"17px",height:"17px"}})})]})};import{useEffect as Ve,useState as U}from"react";import{Fragment as Ye,jsx as T,jsxs as ie}from"react/jsx-runtime";var qe={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",border:"1px solid #03852e",display:"flex",alignItems:"center",gap:"8px",flexShrink:0,height:"34px"},Qe={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",transition:"background-color 0.2s"},Ke={outline:"none",fontSize:"16px",backgroundColor:"transparent",borderRadius:"2px",padding:"2px 8px",width:"64px",textAlign:"center",border:"none"},$e={padding:"4px",borderRadius:"50%",cursor:"pointer",transition:"background-color 0.2s",border:"none",backgroundColor:"transparent",color:"#737373",display:"flex",alignItems:"center",justifyContent:"center"},be=({boundary:e,label:t,value:o,placeholder:a,currency:i,isOptional:p=!1,showRemoveButton:u=!1,removeLabel:c,editLabel:r,showAddWhenEmpty:n=!1,onCommit:s,onRemove:l})=>{let[m,P]=U(o!==void 0?String(o):""),[v,C]=U(!1),[f,S]=U(!1),[x,h]=U(!1),k=o!==void 0;Ve(()=>{P(o!==void 0?String(o):""),C(!1)},[o]);let I=()=>{P(o!==void 0?String(o):"")},A=()=>{if(m.trim()===""){if(p){s(void 0),P("");return}I();return}let y=Number(m);if(!Number.isFinite(y)){I();return}let B=Math.max(0,y);if(B===o){I();return}s(B)};return ie("div",{style:qe,children:[T("span",{style:{fontSize:"10px",textTransform:"uppercase",fontWeight:600,letterSpacing:"0.05em"},children:t}),v?T("input",{value:m,onChange:y=>{let B=y.target.value.replace(/[^\d]/g,"");P(B)},onBlur:()=>{A(),C(!1)},onKeyDown:y=>{if(y.key==="Enter"){y.preventDefault(),y.currentTarget.blur(),C(!1);return}if(y.key==="Escape"){y.preventDefault(),I(),y.currentTarget.blur(),C(!1);return}y.key.length===1&&/[0-9]/.test(y.key)||y.key==="Backspace"||y.key==="Delete"||y.key==="Tab"||y.key==="ArrowLeft"||y.key==="ArrowRight"||y.key==="Home"||y.key==="End"||y.preventDefault()},placeholder:a,inputMode:"numeric",pattern:"[0-9]*","aria-label":t,style:Ke,autoFocus:!0}):k?ie("span",{style:{fontSize:"16px"},children:[i,o]}):n?T("button",{type:"button",style:{fontSize:"16px",color:"#737373",cursor:"pointer",border:"none",backgroundColor:"transparent",padding:0},onClick:()=>C(!0),"aria-label":r,children:"+"}):T("span",{style:{fontSize:"16px",color:"#737373"},children:"-"}),(!n||n&&v)&&T("span",{style:{color:"#737373",fontSize:"12px"},children:i}),!v&&(!n||k)&&T("button",{type:"button",style:{...$e,backgroundColor:f?"#e5e5e5":"transparent"},"aria-label":r,title:r,onClick:()=>C(!0),onMouseEnter:()=>S(!0),onMouseLeave:()=>S(!1),children:T(q,{})}),u&&T("button",{style:{...Qe,backgroundColor:x?"#e5e5e5":"white"},onClick:l,onMouseEnter:()=>h(!0),onMouseLeave:()=>h(!1),"aria-label":c,title:c,children:T(H,{style:{width:"17px",height:"17px"}})})]})},se=({priceRange:e,currency:t,onChange:o,onRemove:a})=>{let{t:i}=M(),p="Min",u="Max",c=i("smartFilter.priceRange.remove"),r=i("smartFilter.priceRange.edit"),n=(s,l)=>{let m={min:e.min,max:e.max};s==="min"?(m.min=l,l!==void 0&&e.max!==void 0&&l>e.max&&(m.max=l)):(m.max=l,l!==void 0&&e.min!==void 0&&l<e.min&&(m.min=l)),(m.min!==e.min||m.max!==e.max)&&o(m)};return ie(Ye,{children:[T(be,{boundary:"min",label:p,value:e.min,currency:t,editLabel:r,showRemoveButton:e.min!==void 0&&e.min!==0,onCommit:s=>n("min",s),onRemove:a}),T(be,{boundary:"max",label:u,value:e.max,currency:t,isOptional:!0,showRemoveButton:e.max!==void 0,removeLabel:c,editLabel:r,showAddWhenEmpty:!0,onCommit:s=>n("max",s),onRemove:a})]})};import je from"react";import{jsx as O,jsxs as Z}from"react/jsx-runtime";var Ge={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",paddingRight:"20px",border:"1px solid #03852e",display:"flex",alignItems:"center",gap:"16px",flexShrink:0,height:"34px"},Ue={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",transition:"background-color 0.2s"},xe=[{value:"Cheap Eats",key:"cheapEats"},{value:"Mid Range",key:"midRange"},{value:"Fine Dining",key:"fineDining"}],ae=({values:e,onChange:t,onRemove:o})=>{let{t:a}=M(),[i,p]=je.useState(!1),u=a("smartFilter.restaurantPriceLevel.label"),c=a("smartFilter.restaurantPriceLevel.remove"),r=a("smartFilter.restaurantPriceLevel.none"),n=s=>{let{value:l,checked:m}=s.target,P=l,v=new Set(e);m?v.add(P):v.delete(P);let C=xe.filter(f=>v.has(f.value)).map(f=>f.value);t(C)};return Z("div",{style:Ge,children:[Z("div",{style:{display:"flex",alignItems:"center",gap:"8px",flexWrap:"wrap"},children:[O("span",{style:{fontSize:"10px",textTransform:"uppercase",fontWeight:600,letterSpacing:"0.05em"},children:u}),Z("div",{style:{display:"flex",gap:"12px"},children:[xe.map(s=>{let l=a(`smartFilter.restaurantPriceLevel.options.${s.key}`),m=`price-level-${s.key}`;return Z("label",{htmlFor:m,style:{display:"flex",alignItems:"center",gap:"4px",fontSize:"12px",cursor:"pointer"},children:[O("input",{id:m,type:"checkbox",value:s.value,checked:e.includes(s.value),onChange:n,style:{accentColor:"#03852e",cursor:"pointer"}}),O("span",{children:l})]},s.value)}),e.length===0&&O("span",{style:{fontSize:"12px",color:"#737373"},children:r})]})]}),O("button",{style:{...Ue,backgroundColor:i?"#e5e5e5":"white"},onClick:o,onMouseEnter:()=>p(!0),onMouseLeave:()=>p(!1),"aria-label":c!=null?c:u,title:c!=null?c:u,children:O(H,{style:{width:"17px",height:"17px"}})})]})};import{useEffect as Ze,useRef as Xe,useState as X}from"react";import{jsx as z,jsxs as nt}from"react/jsx-runtime";var Je={position:"relative",backgroundColor:"white",color:"black",fontSize:"14px",borderRadius:"9999px",padding:"0 16px",paddingRight:"20px",border:"1px solid #03852e",display:"flex",alignItems:"center",gap:"8px",flexShrink:0,userSelect:"none",height:"34px"},et={position:"absolute",top:"-8px",right:"-8px",padding:"2px",borderRadius:"50%",backgroundColor:"white",border:"1px solid #03852e",cursor:"pointer",transition:"background-color 0.2s"},tt={backgroundColor:"#ececec",borderRadius:"2px",padding:"2px 8px",outline:"none",fontSize:"16px",minWidth:"8ch",border:"none"},rt={padding:"4px",borderRadius:"50%",cursor:"pointer",transition:"background-color 0.2s",color:"#737373",border:"none",backgroundColor:"transparent",display:"flex",alignItems:"center",justifyContent:"center"},le=({value:e,onChange:t,onRemove:o})=>{let a=Xe(null),[i,p]=X(e),[u,c]=X(!1),[r,n]=X(!1),[s,l]=X(!1),{t:m}=M(),P=m("smartFilter.transformedQuery.remove"),v=m("smartFilter.transformedQuery.edit");Ze(()=>{p(e),c(!1)},[e]);let C=()=>{let x=i.trim();if(!x.length){p(e);return}x!==e&&t(x)};return nt("div",{style:Je,children:[z(V,{style:{width:"16px",height:"16px",color:"#03852e"}}),u?z("input",{ref:a,value:i,onChange:x=>{p(x.target.value)},onBlur:()=>{C(),c(!1)},onKeyDown:x=>{if(x.key==="Enter"){x.preventDefault(),x.currentTarget.blur();return}if(x.key==="Escape"){x.preventDefault(),p(e),x.currentTarget.blur();return}},"aria-label":v,style:tt,autoFocus:!0}):z("span",{style:{fontSize:"16px"},children:e}),!u&&z("button",{type:"button",style:{...rt,backgroundColor:r?"#e5e5e5":"transparent"},"aria-label":v,title:v,onClick:()=>c(!0),onMouseEnter:()=>n(!0),onMouseLeave:()=>n(!1),children:z(q,{})}),z("button",{style:{...et,backgroundColor:s?"#e5e5e5":"white"},onClick:o,onMouseEnter:()=>l(!0),onMouseLeave:()=>l(!1),"aria-label":P,title:P,children:z(H,{style:{width:"17px",height:"17px"}})})]})};import{useCallback as Se,useEffect as ot,useRef as it,useState as ve}from"react";var ce=e=>{let t=it(null),[o,a]=ve(!0),[i,p]=ve(!0),u=Se(()=>{let r=t.current;if(!r){a(!0),p(!0);return}let{scrollLeft:n,scrollWidth:s,clientWidth:l}=r;a(n<=0),p(n+l>=s-1)},[]);ot(()=>{let r=t.current;if(u(),!r)return;let n=()=>u();return r.addEventListener("scroll",n,{passive:!0}),window.addEventListener("resize",u),()=>{r.removeEventListener("scroll",n),window.removeEventListener("resize",u)}},[e,u]);let c=Se(r=>{let n=t.current;if(!n)return;let s=n.clientWidth*.7;n.scrollBy({left:r==="next"?s:-s,behavior:"smooth"})},[]);return{scrollerRef:t,atStart:o,atEnd:i,scrollByDir:c}};import{jsx as w,jsxs as ke}from"react/jsx-runtime";var st={position:"relative",width:"100%"},at={display:"flex",gap:"8px",overflowX:"auto",alignItems:"center",width:"100%",scrollbarWidth:"none",msOverflowStyle:"none"},Ce={pointerEvents:"none",position:"absolute",top:0,bottom:0,width:"40px"},Pe={position:"absolute",top:"50%",transform:"translateY(-50%)",backgroundColor:"white",color:"#003c30",border:"1px solid #003c30",padding:"4px",borderRadius:"50%",display:"flex",alignItems:"center",justifyContent:"center",boxShadow:"0 1px 3px rgba(0,0,0,0.1)",cursor:"pointer"},ue=({filters:e,isPortrait:t,currency:o,minRatingSuffix:a,clearAllLabel:i,previousFiltersLabel:p,nextFiltersLabel:u,formatCurrency:c,onFilterChange:r,onResetFilters:n,onClearAll:s})=>{let{scrollerRef:l,atStart:m,atEnd:P,scrollByDir:v}=ce(e.length),{t:C}=M(),[f,S]=pe.useState(null),[x,h]=pe.useState(!1),[k,I]=pe.useState(!1),A={...at,padding:t?"8px 16px":"8px"};return ke("div",{style:st,children:[ke("div",{ref:l,style:{...A,WebkitOverflowScrolling:"touch"},children:[w("style",{children:`
2
+ div::-webkit-scrollbar {
3
+ display: none;
4
+ }
5
+ `}),w("button",{style:{flexShrink:0,backgroundColor:x?"#03a03e":"#03852e",borderRadius:"50%",padding:"8px",cursor:"pointer",border:"none",display:"flex",alignItems:"center",justifyContent:"center",transition:"background-color 0.2s"},onClick:n,onMouseEnter:()=>h(!0),onMouseLeave:()=>h(!1),children:w(V,{style:{width:"20px",height:"20px",color:"white"}})}),e.map(d=>{var y,B,_;let W=()=>w(re,{label:d.label,icon:d.icon,remove:()=>{r(e.filter(b=>b.id!==d.id))}},d.id);if(d.type==="minRating"){let b=(y=d.numericValue)!=null?y:Number(d.value);return Number.isFinite(b)?w(G,{rating:b,onChange:R=>{let F=e.map(L=>L.id===d.id?{...L,numericValue:R,value:String(R)}:L);r(F)},onRemove:()=>void r(e.filter(R=>R.id!==d.id))},d.id):W()}if(d.type==="starRating"){let b=(B=d.numericValue)!=null?B:Number(d.value);return Number.isFinite(b)?w(G,{star:!0,rating:b,onChange:R=>{let F=e.map(L=>L.id===d.id?{...L,numericValue:R,value:String(R)}:L);r(F)},onRemove:()=>void r(e.filter(R=>R.id!==d.id))},d.id):W()}return d.type==="priceRange"&&d.priceRange?w(se,{priceRange:d.priceRange,currency:o,onChange:b=>{let R=e.map(F=>F.id===d.id?{...F,priceRange:b}:F);r(R)},onRemove:()=>void r(e.filter(b=>b.id!==d.id))},d.id):d.type==="transformed_query"?w(le,{value:d.value,onChange:b=>{let R=e.map(F=>F.id===d.id?{...F,value:b}:F);r(R)},onRemove:()=>void r(e.filter(b=>b.id!==d.id))},d.id):d.type==="selected_restaurant_price_levels"?w(ae,{values:(_=d.priceLevels)!=null?_:[],onChange:b=>{let R=e.map(F=>F.id===d.id?{...F,priceLevels:b}:F);r(R)},onRemove:()=>void r(e.filter(b=>b.id!==d.id))},d.id):W()}),w("button",{style:{flexShrink:0,padding:"4px 16px",borderRadius:"9999px",cursor:"pointer",fontSize:"14px",userSelect:"none",border:"none",backgroundColor:k?"#e5e5e5":"transparent",transition:"background-color 0.2s"},onClick:s,onMouseEnter:()=>I(!0),onMouseLeave:()=>I(!1),children:i})]}),!m&&w("div",{"aria-hidden":"true",style:{...Ce,left:0,background:"linear-gradient(to right, white, transparent)"}}),!P&&w("div",{"aria-hidden":"true",style:{...Ce,right:0,background:"linear-gradient(to left, white, transparent)"}}),!m&&w("button",{type:"button","aria-label":p,style:{...Pe,left:"4px",transform:"translateY(-50%) rotate(180deg)",backgroundColor:f==="prev"?"#e5e5e5":"white"},onClick:()=>v("prev"),onMouseEnter:()=>S("prev"),onMouseLeave:()=>S(null),children:w(te,{style:{width:"20px",height:"20px"}})}),!P&&w("button",{type:"button","aria-label":u,style:{...Pe,right:"4px",backgroundColor:f==="next"?"#e5e5e5":"white"},onClick:()=>v("next"),onMouseEnter:()=>S("next"),onMouseLeave:()=>S(null),children:w(te,{style:{width:"20px",height:"20px"}})})]})};import{useEffect as lt,useState as ct}from"react";var de=()=>{let[e,t]=ct(typeof window!="undefined"?window.innerHeight>window.innerWidth:!1);return lt(()=>{if(typeof window=="undefined")return;let o=()=>{t(window.innerHeight>window.innerWidth)};return window.addEventListener("resize",o),()=>window.removeEventListener("resize",o)},[]),e};import{jsx as D,jsxs as Re}from"react/jsx-runtime";var ut={position:"relative",display:"flex",flexDirection:"column",gap:"8px",width:"100%"},dt={position:"relative",display:"flex",alignItems:"center",gap:"8px",width:"100%"},mt={position:"relative",display:"flex",alignItems:"center",flex:1,backgroundColor:"white",borderRadius:"24px",border:"1px solid #e5e5e5",padding:"12px 16px",boxShadow:"0 1px 3px rgba(0,0,0,0.1)"},gt={width:"20px",height:"20px",color:"#03852e",flexShrink:0},ft={flex:1,border:"none",outline:"none",fontSize:"16px",backgroundColor:"transparent",color:"#000"},yt={position:"absolute",right:"16px",top:"50%",transform:"translateY(-50%)"},ht={width:"20px",height:"20px",border:"2px solid #e5e5e5",borderTop:"2px solid #03852e",borderRadius:"50%",animation:"spin 1s linear infinite"},bt={position:"absolute",left:"48px",top:"50%",transform:"translateY(-50%)",color:"#737373",pointerEvents:"none",fontSize:"16px"},xt=({mapFirst:e,filters:t,value:o,isSearching:a=!1,placeholder:i,onSearch:p,onFilterChange:u,onValueChange:c,showTypingPrompt:r=!0,customTranslations:n,currency:s="USD",style:l,inputStyle:m,containerStyle:P})=>{let[v,C]=pt(""),f=o!==void 0?o:v,S=c||C,x=de(),{t:h,formatCurrency:k}=M(n),I=h("smartFilter.minRating.suffix"),A=i||h("smartFilter.placeholder"),d=h("smartFilter.typingPrompt"),W=h("smartFilter.nav.previous"),y=h("smartFilter.nav.next"),B=h("smartFilter.clearAll"),_=async L=>{L.preventDefault();let J=f.trim();if(!(!J||a))try{await p(J)}catch(ee){console.error("Search error:",ee)}},b=me(async(L,J)=>{if(!a)try{await u(L)}catch(ee){console.error("Filter change error:",ee)}},[a,u]),R=me(()=>{b([])},[b]),F=me(()=>{b([],!0),S("")},[b,S]);return Re("div",{style:{...ut,...P},children:[D("style",{children:`
6
+ @keyframes spin {
7
+ 0% { transform: rotate(0deg); }
8
+ 100% { transform: rotate(360deg); }
9
+ }
10
+ `}),D("form",{onSubmit:_,style:{...dt,...l},children:Re("div",{style:mt,children:[D(ge,{style:gt}),D("input",{type:"text",value:f,onChange:L=>S(L.target.value),placeholder:A,disabled:a,style:{...ft,...m},autoComplete:"off","aria-label":"Smart search"}),r&&f.length===0&&!a&&D("span",{style:bt,children:d}),a&&D("div",{style:yt,children:D("div",{style:ht})})]})}),t.length>0&&D(ue,{filters:t,isPortrait:x,currency:s,minRatingSuffix:I,clearAllLabel:B,previousFiltersLabel:W,nextFiltersLabel:y,formatCurrency:k,onFilterChange:b,onResetFilters:R,onClearAll:F})]})};import{jsx as Fe,jsxs as we}from"react/jsx-runtime";function un(e){let t=g.useRef(null),[o,a]=g.useState(null),i=g.useRef(e);return g.useEffect(()=>{i.current=e}),g.useEffect(()=>{let p=i.current,u={adapter:null,...p,callbacks:{...p.callbacks,onPropertiesChange:r=>{var n,s;a(l=>l?{...l,properties:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onPropertiesChange)==null||s.call(n,r)},onSelectedPropertyChange:r=>{var n,s;a(l=>l?{...l,selectedPropertyId:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onSelectedPropertyChange)==null||s.call(n,r)},onPrimaryTypeChange:r=>{var n,s;a(l=>l?{...l,primary:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onPrimaryTypeChange)==null||s.call(n,r)},onFiltersChange:r=>{var n,s;a(l=>l?{...l,filters:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onFiltersChange)==null||s.call(n,r)},onBoundsChange:r=>{var n,s;a(l=>l?{...l,bounds:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onBoundsChange)==null||s.call(n,r)},onCenterChange:(r,n)=>{var s,l;a(m=>m?{...m,center:r,zoom:n}:null),(l=(s=i.current.callbacks)==null?void 0:s.onCenterChange)==null||l.call(s,r,n)},onZoomChange:r=>{var n,s;a(l=>l?{...l,zoom:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onZoomChange)==null||s.call(n,r)},onActiveLocationChange:r=>{var n,s;a(l=>l?{...l,activeLocation:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onActiveLocationChange)==null||s.call(n,r)},onLoadingStateChange:r=>{var n,s;a(l=>l?{...l,initialLoading:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onLoadingStateChange)==null||s.call(n,r)},onSearchingStateChange:r=>{var n,s;a(l=>l?{...l,isSearching:r}:null),(s=(n=i.current.callbacks)==null?void 0:n.onSearchingStateChange)==null||s.call(n,r)}}},c=new Le(u);return t.current=c,a(c.getState()),()=>{c.destroy(),t.current=null,a(null)}},[]),{mapFirst:t.current,state:o}}function dn(e){let[t,o]=g.useState([]);return g.useEffect(()=>{if(!e){o([]);return}o(e.getState().properties)},[e]),t}function mn(e){let[t,o]=g.useState(null);return g.useEffect(()=>{if(!e){o(null);return}o(e.getState().selectedPropertyId)},[e]),t}function gn(e){let[t,o]=g.useState("Accommodation");g.useEffect(()=>{if(!e){o("Accommodation");return}o(e.getState().primary)},[e]);let a=g.useCallback(i=>{e&&(e.setPrimaryType(i),o(i))},[e]);return[t,a]}function fn(e){let[t,o]=g.useState(null);g.useEffect(()=>{if(!e){o(null);return}o(e.getState().selectedPropertyId)},[e]);let a=g.useCallback(i=>{e&&e.setSelectedMarker(i)},[e]);return[t,a]}function yn({mapFirst:e,map:t,maplibregl:o,onMarkerClick:a}){let i=g.useRef(!1);g.useEffect(()=>{!e||!t||i.current||(e.attachMap(t,{platform:"maplibre",maplibregl:o,onMarkerClick:a}),i.current=!0)},[e,t,o,a])}function hn({mapFirst:e,map:t,google:o,onMarkerClick:a}){let i=g.useRef(!1);g.useEffect(()=>{!e||!t||i.current||(e.attachMap(t,{platform:"google",google:o,onMarkerClick:a}),i.current=!0)},[e,t,o,a])}function bn({mapFirst:e,map:t,mapboxgl:o,onMarkerClick:a}){let i=g.useRef(!1);g.useEffect(()=>{!e||!t||i.current||(e.attachMap(t,{platform:"mapbox",mapboxgl:o,onMarkerClick:a}),i.current=!0)},[e,t,o,a])}function xn(e){let t=g.useRef(null);return g.useEffect(()=>{if(!e)return;let o=new Le(e);return t.current=o,()=>{o.destroy(),t.current=null}},[e]),t}function Sn(e){let[t,o]=g.useState(!1),[a,i]=g.useState(null);return{search:g.useCallback(async u=>{if(!e){let c=new Error("MapFirst instance not available");throw i(c),c}o(!0),i(null);try{return await e.runPropertiesSearch({...u,onError:r=>{let n=r instanceof Error?r:new Error(String(r));i(n)}})}catch(c){let r=c instanceof Error?c:new Error(String(c));throw i(r),r}finally{o(!1)}},[e]),isLoading:t,error:a}}function vn(e){let[t,o]=g.useState(!1),[a,i]=g.useState(null);return{search:g.useCallback(async u=>{if(!e){let c=new Error("MapFirst instance not available");throw i(c),c}o(!0),i(null);try{return await e.runSmartFilterSearch({...u,onError:r=>{let n=r instanceof Error?r:new Error(String(r));i(n)}})}catch(c){let r=c instanceof Error?c:new Error(String(c));throw i(r),r}finally{o(!1)}},[e]),isLoading:t,error:a}}function Cn({markers:e}){return we("div",{style:{fontFamily:"sans-serif",fontSize:14},children:[Fe("strong",{children:"Markers"}),Fe("ul",{children:e.map(t=>{var o,a,i,p,u,c;return we("li",{children:[t.name," \u2014 ",(i=(a=(o=t.location)==null?void 0:o.lat)==null?void 0:a.toFixed(3))!=null?i:"n/a",","," ",(c=(u=(p=t.location)==null?void 0:p.lon)==null?void 0:u.toFixed(3))!=null?c:"n/a"]},String(t.tripadvisor_id))})})]})}export{ge as AiIcon,re as Chip,H as CloseIcon,q as EditIcon,ue as FilterChips,Cn as MarkerDebugList,G as MinRatingFilterChip,te as NextIcon,se as PriceRangeFilterChip,ae as RestaurantPriceLevelChip,V as SearchIcon,xt as SmartFilter,fe as StarIcon,le as TransformedQueryChip,Mt as createMinRatingFilterLabel,It as createPriceRangeFilterLabel,ne as formatRatingValue,Ae as renderStars,ce as useFilterScroll,hn as useGoogleMapsAttachment,de as useIsPortrait,xn as useMapFirst,un as useMapFirstCore,dn as useMapFirstProperties,mn as useMapFirstSelectedProperty,yn as useMapLibreAttachment,bn as useMapboxAttachment,gn as usePrimaryType,Sn as usePropertiesSearch,fn as useSelectedMarker,vn as useSmartFilterSearch,M as useTranslation};
2
11
  //# sourceMappingURL=index.mjs.map