@zonetrix/viewer 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -108,6 +108,7 @@ function BookingApp() {
108
108
  | `onFloorChange` | `(floorId: string) => void` | No | Callback when floor changes |
109
109
  | `reservedSeats` | `string[]` | No | Array of seat IDs/numbers to mark as reserved |
110
110
  | `unavailableSeats` | `string[]` | No | Array of seat IDs/numbers to mark as unavailable |
111
+ | `selectedSeats` | `string[]` | No | Array of seat IDs for controlled selection mode |
111
112
  | `onSeatSelect` | `(seat: SeatData) => void` | No | Callback when a seat is selected |
112
113
  | `onSeatDeselect` | `(seat: SeatData) => void` | No | Callback when a seat is deselected |
113
114
  | `onSelectionChange` | `(seats: SeatData[]) => void` | No | Callback when selection changes |
@@ -341,7 +342,88 @@ function CustomFloorSelector() {
341
342
  }
342
343
  ```
343
344
 
344
- ### 7. Error Handling
345
+ ### 7. Controlled Selection Mode
346
+
347
+ For complete control over seat selection state (e.g., syncing with external state, URL params, or database):
348
+
349
+ ```tsx
350
+ import { useState } from 'react';
351
+ import { SeatMapViewer } from '@zonetrix/viewer';
352
+ import type { SeatData } from '@zonetrix/viewer';
353
+
354
+ function ControlledSelection() {
355
+ const [selectedSeatIds, setSelectedSeatIds] = useState<string[]>([]);
356
+
357
+ const handleSeatSelect = (seat: SeatData) => {
358
+ setSelectedSeatIds(prev => [...prev, seat.id]);
359
+ };
360
+
361
+ const handleSeatDeselect = (seat: SeatData) => {
362
+ setSelectedSeatIds(prev => prev.filter(id => id !== seat.id));
363
+ };
364
+
365
+ return (
366
+ <SeatMapViewer
367
+ config={venueConfig}
368
+ selectedSeats={selectedSeatIds} // Controlled mode
369
+ onSeatSelect={handleSeatSelect}
370
+ onSeatDeselect={handleSeatDeselect}
371
+ />
372
+ );
373
+ }
374
+ ```
375
+
376
+ **Use cases for controlled selection mode:**
377
+ - Syncing selection with URL query parameters
378
+ - Persisting selection in Redux/Zustand store
379
+ - Loading pre-selected seats from database
380
+ - Implementing undo/redo functionality
381
+ - Syncing selection across multiple components
382
+ - Integrating with shopping cart state management
383
+
384
+ **Example with cart integration:**
385
+
386
+ ```tsx
387
+ import { useState } from 'react';
388
+ import { SeatMapViewer } from '@zonetrix/viewer';
389
+ import type { SeatData } from '@zonetrix/viewer';
390
+
391
+ function CartIntegration() {
392
+ const [cartItems, setCartItems] = useState<SeatData[]>([]);
393
+
394
+ // Derive selected IDs from cart
395
+ const selectedSeatIds = cartItems.map(seat => seat.id);
396
+
397
+ const handleSeatSelect = (seat: SeatData) => {
398
+ setCartItems(prev => [...prev, seat]);
399
+ };
400
+
401
+ const handleSeatDeselect = (seat: SeatData) => {
402
+ setCartItems(prev => prev.filter(item => item.id !== seat.id));
403
+ };
404
+
405
+ const totalPrice = cartItems.reduce((sum, seat) => sum + (seat.price || 0), 0);
406
+
407
+ return (
408
+ <div>
409
+ <SeatMapViewer
410
+ config={venueConfig}
411
+ selectedSeats={selectedSeatIds}
412
+ onSeatSelect={handleSeatSelect}
413
+ onSeatDeselect={handleSeatDeselect}
414
+ />
415
+
416
+ <div className="cart">
417
+ <h3>Shopping Cart</h3>
418
+ <p>Selected: {cartItems.length} seat(s)</p>
419
+ <p>Total: ${totalPrice.toFixed(2)}</p>
420
+ </div>
421
+ </div>
422
+ );
423
+ }
424
+ ```
425
+
426
+ ### 8. Error Handling
345
427
 
346
428
  ```tsx
347
429
  import { SeatMapViewer } from '@zonetrix/viewer';
@@ -7,6 +7,7 @@ export interface SeatMapViewerProps {
7
7
  onFloorChange?: (floorId: string) => void;
8
8
  reservedSeats?: string[];
9
9
  unavailableSeats?: string[];
10
+ selectedSeats?: string[];
10
11
  onSeatSelect?: (seat: SeatData) => void;
11
12
  onSeatDeselect?: (seat: SeatData) => void;
12
13
  onSelectionChange?: (seats: SeatData[]) => void;
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),e=require("react"),L=require("react-konva");function dt(n){const[i,d]=e.useState(null),[r,b]=e.useState(!1),[S,p]=e.useState(null),v=async()=>{if(n){b(!0),p(null);try{const y=await fetch(n);if(!y.ok)throw new Error(`Failed to fetch config: ${y.statusText}`);const a=await y.json();d(a)}catch(y){const a=y instanceof Error?y:new Error("Unknown error occurred");p(a),console.error("Failed to fetch seat map config:",a)}finally{b(!1)}}};return e.useEffect(()=>{v()},[n]),{config:i,loading:r,error:S,refetch:v}}function ft(n){const[i,d]=e.useState({width:0,height:0});return e.useEffect(()=>{const r=n.current;if(!r)return;const{width:b,height:S}=r.getBoundingClientRect();b>0&&S>0&&d({width:b,height:S});const p=new ResizeObserver(v=>{const y=v[0];if(!y)return;const{width:a,height:s}=y.contentRect;a>0&&s>0&&d(u=>u.width===a&&u.height===s?u:{width:a,height:s})});return p.observe(r),()=>{p.disconnect()}},[n]),i}function ut(n,i){return Math.sqrt(Math.pow(i.x-n.x,2)+Math.pow(i.y-n.y,2))}function ht(n,i){return{x:(n.x+i.x)/2,y:(n.y+i.y)/2}}function xt(n,i){const d=e.useRef(null),r=e.useRef(null),b=e.useRef(1);e.useEffect(()=>{const S=n.current;if(!S||!i.enabled)return;const p=S.container(),v=s=>{if(s.touches.length===2){s.preventDefault();const u={x:s.touches[0].clientX,y:s.touches[0].clientY},g={x:s.touches[1].clientX,y:s.touches[1].clientY};d.current=ut(u,g),r.current=ht(u,g),b.current=i.currentScale}},y=s=>{if(s.touches.length!==2)return;s.preventDefault();const u={x:s.touches[0].clientX,y:s.touches[0].clientY},g={x:s.touches[1].clientX,y:s.touches[1].clientY},k=ut(u,g),C=ht(u,g);if(d.current!==null&&r.current!==null){const R=k/d.current,P=Math.min(Math.max(i.currentScale*R,i.minScale),i.maxScale),V=p.getBoundingClientRect(),_=C.x-V.left,G=C.y-V.top,W=i.currentScale,T={x:(_-i.currentPosition.x)/W,y:(G-i.currentPosition.y)/W},et=C.x-r.current.x,nt=C.y-r.current.y,ot={x:_-T.x*P+et,y:G-T.y*P+nt};i.onScaleChange(P,ot),d.current=k,r.current=C}},a=s=>{s.touches.length<2&&(d.current=null,r.current=null)};return p.addEventListener("touchstart",v,{passive:!1}),p.addEventListener("touchmove",y,{passive:!1}),p.addEventListener("touchend",a),()=>{p.removeEventListener("touchstart",v),p.removeEventListener("touchmove",y),p.removeEventListener("touchend",a)}},[n,i])}const pt={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},gt=e.memo(({seat:n,state:i,colors:d,onClick:r,onMouseEnter:b,onMouseLeave:S})=>{const y={available:d.seatAvailable,reserved:d.seatReserved,selected:d.seatSelected,unavailable:d.seatUnavailable,hidden:d.seatHidden}[i],a=i==="available"||i==="selected",s=e.useCallback(()=>{a&&r(n)},[n,r,a]),u=e.useCallback(C=>{b(n,C);const R=C.target.getStage();R&&a&&(R.container().style.cursor="pointer")},[n,b,a]),g=e.useCallback(C=>{S();const R=C.target.getStage();R&&(R.container().style.cursor="grab")},[S]),k={x:n.position.x,y:n.position.y,fill:y,stroke:"#ffffff",strokeWidth:1,onClick:s,onTap:s,onMouseEnter:u,onMouseLeave:g};return n.shape==="circle"?o.jsx(L.Circle,{...k,radius:12}):o.jsx(L.Rect,{...k,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});gt.displayName="ViewerSeat";const yt=e.memo(({stage:n,stageColor:i})=>o.jsxs(L.Group,{x:n.position.x,y:n.position.y,children:[o.jsx(L.Rect,{width:n.config.width,height:n.config.height,fill:i+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),o.jsx(L.Text,{text:n.config.label,x:0,y:0,width:n.config.width,height:n.config.height,fontSize:24,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]}));yt.displayName="ViewerStage";const mt=e.memo(({floors:n,currentFloorId:i,onFloorChange:d,showAllOption:r,allLabel:b,position:S,className:p})=>{const v=e.useMemo(()=>[...n].sort((g,k)=>g.order-k.order),[n]),a={position:"absolute",display:"flex",alignItems:"center",gap:"8px",padding:"8px 12px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[S]},s={padding:"10px 16px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease",minHeight:"44px",touchAction:"manipulation"},u={...s,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return o.jsxs("div",{className:p,style:a,children:[r&&o.jsx("button",{type:"button",onClick:()=>d(null),style:i===null?u:s,children:b}),v.map(g=>o.jsx("button",{type:"button",onClick:()=>d(g.id),style:i===g.id?u:s,children:g.name},g.id))]})});mt.displayName="FloorSelectorBar";const bt=e.memo(({scale:n,minScale:i,maxScale:d,onZoomIn:r,onZoomOut:b,position:S,className:p})=>{const y={position:"absolute",display:"flex",flexDirection:"column",gap:"4px",padding:"8px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[S]},a={width:"44px",height:"44px",minWidth:"44px",minHeight:"44px",fontSize:"22px",fontWeight:"bold",border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s ease",touchAction:"manipulation"},s={...a,opacity:.4,cursor:"not-allowed"},u=n<d,g=n>i;return o.jsxs("div",{className:p,style:y,children:[o.jsx("button",{type:"button",onClick:r,disabled:!u,style:u?a:s,title:"Zoom In",children:"+"}),o.jsx("button",{type:"button",onClick:b,disabled:!g,style:g?a:s,title:"Zoom Out",children:"−"})]})});bt.displayName="ZoomControls";const St=e.memo(({visible:n,x:i,y:d,seat:r,currency:b,state:S})=>{if(!n||!r)return null;const p=r.seatNumber||(r.rowLabel&&r.columnLabel?`${r.rowLabel}-${r.columnLabel}`:"N/A"),v={position:"fixed",left:`${i+15}px`,top:`${d+15}px`,zIndex:1e3,pointerEvents:"none"},y={backgroundColor:"rgba(26, 26, 26, 0.95)",color:"#fff",border:"1px solid #444",borderRadius:"8px",padding:"8px 12px",fontSize:"13px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)",minWidth:"140px"},a={color:"#9ca3af",marginRight:"4px"},s={fontWeight:600},u={color:"#4ade80",fontWeight:600},g={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return o.jsx("div",{style:v,children:o.jsxs("div",{style:y,children:[r.sectionName&&o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Section:"}),o.jsx("span",{style:{...s,color:"#3b82f6"},children:r.sectionName})]}),o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Seat:"}),o.jsx("span",{style:s,children:p})]}),r.price!==void 0&&r.price>0&&o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Price:"}),o.jsxs("span",{style:u,children:[b," ",r.price.toFixed(2)]})]}),o.jsxs("div",{style:g,children:["Status: ",S]})]})})});St.displayName="SeatTooltip";const Vt=({config:n,configUrl:i,floorId:d,onFloorChange:r,reservedSeats:b=[],unavailableSeats:S=[],onSeatSelect:p,onSeatDeselect:v,onSelectionChange:y,colorOverrides:a,showTooltip:s=!0,zoomEnabled:u=!0,className:g="",onConfigLoad:k,onError:C,showFloorSelector:R,floorSelectorPosition:P="top-left",floorSelectorClassName:V,showAllFloorsOption:_=!0,allFloorsLabel:G="All",fitToView:W=!0,fitPadding:T=40,showZoomControls:et=!0,zoomControlsPosition:nt="bottom-right",zoomControlsClassName:ot,maxZoom:I=3,zoomStep:U=.25,touchEnabled:vt=!0})=>{const st=e.useRef(null),at=e.useRef(null),w=ft(at),[X,wt]=e.useState(new Set),[j,A]=e.useState(1),[M,D]=e.useState({x:0,y:0}),[Ct,jt]=e.useState(null),[Mt,kt]=e.useState(1),Z=e.useRef({width:0,height:0}),[B,lt]=e.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Rt,loading:Et,error:z}=dt(i),l=n||Rt,it=d!==void 0,E=it?d||null:Ct,It=e.useCallback(t=>{it||jt(t),r?.(t)},[it,r]),rt=l?.floors||[],Nt=R!==void 0?R:rt.length>1,K=e.useMemo(()=>l?{...l.colors,...a}:{...pt,...a},[l,a]),Y=e.useMemo(()=>{if(!l)return[];let t=l.seats.filter(c=>c.state!=="hidden");return E&&(t=t.filter(c=>c.floorId===E||!c.floorId&&E==="floor_default")),t},[l,E]),J=e.useMemo(()=>l?.stages?E?l.stages.filter(t=>t.floorId===E||!t.floorId&&E==="floor_default"):l.stages:[],[l,E]),N=e.useMemo(()=>{if(!l||Y.length===0&&J.length===0)return null;const t=12;let c=1/0,f=1/0,h=-1/0,x=-1/0;return Y.forEach(m=>{c=Math.min(c,m.position.x-t),f=Math.min(f,m.position.y-t),h=Math.max(h,m.position.x+t),x=Math.max(x,m.position.y+t)}),J.forEach(m=>{c=Math.min(c,m.position.x),f=Math.min(f,m.position.y),h=Math.max(h,m.position.x+(m.config?.width||200)),x=Math.max(x,m.position.y+(m.config?.height||100))}),{minX:c,minY:f,maxX:h,maxY:x,width:h-c,height:x-f}},[l,Y,J]);e.useEffect(()=>{if(!W||!l||!N||w.width===0||w.height===0)return;const t=Math.abs(w.width-Z.current.width),c=Math.abs(w.height-Z.current.height);if(!(Z.current.width===0)&&t<10&&c<10)return;Z.current=w;const h=w.width,x=w.height,m=h-T*2,q=x-T*2,Q=m/N.width,ct=q/N.height,tt=Math.min(Q,ct,I),Bt=N.minX+N.width/2,zt=N.minY+N.height/2,$t=h/2,Ht=x/2,Ot=$t-Bt*tt,qt=Ht-zt*tt;A(tt),D({x:Ot,y:qt}),kt(tt)},[W,l,N,T,I,w,E]);const $=e.useMemo(()=>{const t=new Set(b),c=new Set(S);return{reserved:t,unavailable:c}},[b,S]),H=e.useCallback(t=>{const c=t.id,f=t.seatNumber||"";return $.unavailable.has(c)||$.unavailable.has(f)?"unavailable":$.reserved.has(c)||$.reserved.has(f)?"reserved":X.has(c)?"selected":t.state},[$,X]);e.useEffect(()=>{l&&k&&k(l)},[l,k]),e.useEffect(()=>{z&&C&&C(z)},[z,C]);const Lt=e.useCallback(t=>{const c=H(t);if(c!=="available"&&c!=="selected")return;const f=X.has(t.id);wt(h=>{const x=new Set(h);return f?x.delete(t.id):x.add(t.id),x}),f?v?.(t):(p?.(t),p||console.log("Seat selected:",t))},[H,X,p,v]),O=e.useMemo(()=>l?Y.filter(t=>X.has(t.id)):[],[Y,X]);e.useEffect(()=>{y?.(O)},[O,y]);const F=Mt,Dt=e.useCallback(()=>{if(!u)return;const t=Math.min(j+U,I);if(t!==j){const c=w.width||l?.canvas.width||800,f=w.height||l?.canvas.height||600,h=c/2,x=f/2,m={x:(h-M.x)/j,y:(x-M.y)/j};A(t),D({x:h-m.x*t,y:x-m.y*t})}},[u,j,U,I,w,l,M]),Tt=e.useCallback(()=>{if(!u)return;const t=Math.max(j-U,F);if(t!==j){const c=w.width||l?.canvas.width||800,f=w.height||l?.canvas.height||600,h=c/2,x=f/2,m={x:(h-M.x)/j,y:(x-M.y)/j};A(t),D({x:h-m.x*t,y:x-m.y*t})}},[u,j,U,F,w,l,M]),Xt=e.useCallback(t=>{D({x:t.target.x(),y:t.target.y()})},[]),Yt=e.useCallback(t=>{if(!u)return;t.evt.preventDefault();const c=st.current;if(!c)return;const f=c.scaleX(),h=c.getPointerPosition();if(!h)return;const x=1.1,m=t.evt.deltaY>0?f/x:f*x,q=Math.min(Math.max(m,F),I),Q={x:(h.x-M.x)/f,y:(h.y-M.y)/f},ct={x:h.x-Q.x*q,y:h.y-Q.y*q};A(q),D(ct)},[u,M,F,I]);xt(st,{enabled:vt&&u,minScale:F,maxScale:I,currentScale:j,currentPosition:M,onScaleChange:(t,c)=>{A(t),D(c)},onPositionChange:t=>{D(t)}});const Ft=e.useCallback((t,c)=>{if(!s)return;const f=c.target.getStage();if(!f)return;const h=f.getPointerPosition();if(!h)return;const x=f.container().getBoundingClientRect();lt({visible:!0,x:x.left+h.x,y:x.top+h.y,seat:t,state:H(t)})},[s,H]),Pt=e.useCallback(()=>{lt(t=>({...t,visible:!1}))},[]);if(Et)return o.jsx("div",{className:`flex items-center justify-center h-full ${g}`,children:o.jsx("p",{children:"Loading seat map..."})});if(z)return o.jsx("div",{className:`flex items-center justify-center h-full ${g}`,children:o.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",z.message]})});if(!l)return o.jsx("div",{className:`flex items-center justify-center h-full ${g}`,children:o.jsx("p",{children:"No configuration provided"})});const Wt=w.width||l.canvas.width,At=w.height||l.canvas.height;return o.jsxs("div",{ref:at,className:`relative ${g}`,style:{width:"100%",height:"100%"},children:[Nt&&rt.length>0&&o.jsx(mt,{floors:rt,currentFloorId:E,onFloorChange:It,showAllOption:_,allLabel:G,position:P,className:V}),o.jsxs(L.Stage,{ref:st,width:Wt,height:At,scaleX:j,scaleY:j,x:M.x,y:M.y,draggable:!0,onDragEnd:Xt,onWheel:Yt,style:{backgroundColor:l.canvas.backgroundColor,cursor:"grab"},children:[o.jsx(L.Layer,{listening:!1,children:J.map(t=>o.jsx(yt,{stage:t,stageColor:K.stageColor},t.id))}),o.jsx(L.Layer,{children:Y.map(t=>o.jsx(gt,{seat:t,state:H(t),colors:K,onClick:Lt,onMouseEnter:Ft,onMouseLeave:Pt},t.id))})]}),s&&o.jsx(St,{visible:B.visible,x:B.x,y:B.y,seat:B.seat,currency:K.currency,state:B.state}),et&&u&&o.jsx(bt,{scale:j,minScale:F,maxScale:I,onZoomIn:Dt,onZoomOut:Tt,position:nt,className:ot}),O.length>0&&o.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[o.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",O.length,")"]}),o.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:O.map(t=>o.jsxs("div",{className:"text-sm",children:[t.seatNumber,t.price&&` - ${K.currency} ${t.price.toFixed(2)}`]},t.id))})]})]})};exports.DEFAULT_COLORS=pt;exports.SeatMapViewer=Vt;exports.useConfigFetcher=dt;exports.useContainerSize=ft;exports.useTouchGestures=xt;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("react/jsx-runtime"),e=require("react"),L=require("react-konva");function pt(n){const[i,d]=e.useState(null),[r,b]=e.useState(!1),[S,x]=e.useState(null),v=async()=>{if(n){b(!0),x(null);try{const y=await fetch(n);if(!y.ok)throw new Error(`Failed to fetch config: ${y.statusText}`);const a=await y.json();d(a)}catch(y){const a=y instanceof Error?y:new Error("Unknown error occurred");x(a),console.error("Failed to fetch seat map config:",a)}finally{b(!1)}}};return e.useEffect(()=>{v()},[n]),{config:i,loading:r,error:S,refetch:v}}function gt(n){const[i,d]=e.useState({width:0,height:0});return e.useEffect(()=>{const r=n.current;if(!r)return;const{width:b,height:S}=r.getBoundingClientRect();b>0&&S>0&&d({width:b,height:S});const x=new ResizeObserver(v=>{const y=v[0];if(!y)return;const{width:a,height:s}=y.contentRect;a>0&&s>0&&d(g=>g.width===a&&g.height===s?g:{width:a,height:s})});return x.observe(r),()=>{x.disconnect()}},[n]),i}function ft(n,i){return Math.sqrt(Math.pow(i.x-n.x,2)+Math.pow(i.y-n.y,2))}function xt(n,i){return{x:(n.x+i.x)/2,y:(n.y+i.y)/2}}function yt(n,i){const d=e.useRef(null),r=e.useRef(null),b=e.useRef(1);e.useEffect(()=>{const S=n.current;if(!S||!i.enabled)return;const x=S.container(),v=s=>{if(s.touches.length===2){s.preventDefault();const g={x:s.touches[0].clientX,y:s.touches[0].clientY},u={x:s.touches[1].clientX,y:s.touches[1].clientY};d.current=ft(g,u),r.current=xt(g,u),b.current=i.currentScale}},y=s=>{if(s.touches.length!==2)return;s.preventDefault();const g={x:s.touches[0].clientX,y:s.touches[0].clientY},u={x:s.touches[1].clientX,y:s.touches[1].clientY},M=ft(g,u),C=xt(g,u);if(d.current!==null&&r.current!==null){const R=M/d.current,T=Math.min(Math.max(i.currentScale*R,i.minScale),i.maxScale),V=x.getBoundingClientRect(),_=C.x-V.left,G=C.y-V.top,U=i.currentScale,P={x:(_-i.currentPosition.x)/U,y:(G-i.currentPosition.y)/U},W=C.x-r.current.x,ot=C.y-r.current.y,st={x:_-P.x*T+W,y:G-P.y*T+ot};i.onScaleChange(T,st),d.current=M,r.current=C}},a=s=>{s.touches.length<2&&(d.current=null,r.current=null)};return x.addEventListener("touchstart",v,{passive:!1}),x.addEventListener("touchmove",y,{passive:!1}),x.addEventListener("touchend",a),()=>{x.removeEventListener("touchstart",v),x.removeEventListener("touchmove",y),x.removeEventListener("touchend",a)}},[n,i])}const mt={canvasBackground:"#1a1a1a",stageColor:"#808080",seatAvailable:"#2C2B30",seatReserved:"#FCEA00",seatSelected:"#3A7DE5",seatUnavailable:"#6b7280",seatHidden:"#4a4a4a",gridLines:"#404040",currency:"KD"},bt=e.memo(({seat:n,state:i,colors:d,onClick:r,onMouseEnter:b,onMouseLeave:S})=>{const y={available:d.seatAvailable,reserved:d.seatReserved,selected:d.seatSelected,unavailable:d.seatUnavailable,hidden:d.seatHidden}[i],a=i==="available"||i==="selected",s=e.useCallback(()=>{a&&r(n)},[n,r,a]),g=e.useCallback(C=>{b(n,C);const R=C.target.getStage();R&&a&&(R.container().style.cursor="pointer")},[n,b,a]),u=e.useCallback(C=>{S();const R=C.target.getStage();R&&(R.container().style.cursor="grab")},[S]),M={x:n.position.x,y:n.position.y,fill:y,stroke:"#ffffff",strokeWidth:1,onClick:s,onTap:s,onMouseEnter:g,onMouseLeave:u};return n.shape==="circle"?o.jsx(L.Circle,{...M,radius:12}):o.jsx(L.Rect,{...M,width:24,height:24,offsetX:12,offsetY:12,cornerRadius:n.shape==="square"?0:4})});bt.displayName="ViewerSeat";const St=e.memo(({stage:n,stageColor:i})=>o.jsxs(L.Group,{x:n.position.x,y:n.position.y,children:[o.jsx(L.Rect,{width:n.config.width,height:n.config.height,fill:i+"80",stroke:"#ffffff",strokeWidth:2,cornerRadius:10}),o.jsx(L.Text,{text:n.config.label,x:0,y:0,width:n.config.width,height:n.config.height,fontSize:24,fontStyle:"bold",fill:"#ffffff",align:"center",verticalAlign:"middle"})]}));St.displayName="ViewerStage";const vt=e.memo(({floors:n,currentFloorId:i,onFloorChange:d,showAllOption:r,allLabel:b,position:S,className:x})=>{const v=e.useMemo(()=>[...n].sort((u,M)=>u.order-M.order),[n]),a={position:"absolute",display:"flex",alignItems:"center",gap:"8px",padding:"8px 12px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[S]},s={padding:"10px 16px",fontSize:"14px",fontWeight:500,border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",transition:"all 0.2s ease",minHeight:"44px",touchAction:"manipulation"},g={...s,backgroundColor:"#3A7DE5",borderColor:"#3A7DE5"};return o.jsxs("div",{className:x,style:a,children:[r&&o.jsx("button",{type:"button",onClick:()=>d(null),style:i===null?g:s,children:b}),v.map(u=>o.jsx("button",{type:"button",onClick:()=>d(u.id),style:i===u.id?g:s,children:u.name},u.id))]})});vt.displayName="FloorSelectorBar";const wt=e.memo(({scale:n,minScale:i,maxScale:d,onZoomIn:r,onZoomOut:b,position:S,className:x})=>{const y={position:"absolute",display:"flex",flexDirection:"column",gap:"4px",padding:"8px",backgroundColor:"rgba(26, 26, 26, 0.95)",borderRadius:"8px",margin:"12px",zIndex:10,...{"top-left":{top:0,left:0},"top-right":{top:0,right:0},"bottom-left":{bottom:0,left:0},"bottom-right":{bottom:0,right:0}}[S]},a={width:"44px",height:"44px",minWidth:"44px",minHeight:"44px",fontSize:"22px",fontWeight:"bold",border:"1px solid #444",borderRadius:"6px",backgroundColor:"transparent",color:"#fff",cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",transition:"all 0.2s ease",touchAction:"manipulation"},s={...a,opacity:.4,cursor:"not-allowed"},g=n<d,u=n>i;return o.jsxs("div",{className:x,style:y,children:[o.jsx("button",{type:"button",onClick:r,disabled:!g,style:g?a:s,title:"Zoom In",children:"+"}),o.jsx("button",{type:"button",onClick:b,disabled:!u,style:u?a:s,title:"Zoom Out",children:"−"})]})});wt.displayName="ZoomControls";const Ct=e.memo(({visible:n,x:i,y:d,seat:r,currency:b,state:S})=>{if(!n||!r)return null;const x=r.seatNumber||(r.rowLabel&&r.columnLabel?`${r.rowLabel}-${r.columnLabel}`:"N/A"),v={position:"fixed",left:`${i+15}px`,top:`${d+15}px`,zIndex:1e3,pointerEvents:"none"},y={backgroundColor:"rgba(26, 26, 26, 0.95)",color:"#fff",border:"1px solid #444",borderRadius:"8px",padding:"8px 12px",fontSize:"13px",boxShadow:"0 4px 12px rgba(0, 0, 0, 0.3)",minWidth:"140px"},a={color:"#9ca3af",marginRight:"4px"},s={fontWeight:600},g={color:"#4ade80",fontWeight:600},u={fontSize:"11px",color:"#6b7280",textTransform:"capitalize",marginTop:"4px"};return o.jsx("div",{style:v,children:o.jsxs("div",{style:y,children:[r.sectionName&&o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Section:"}),o.jsx("span",{style:{...s,color:"#3b82f6"},children:r.sectionName})]}),o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Seat:"}),o.jsx("span",{style:s,children:x})]}),r.price!==void 0&&r.price>0&&o.jsxs("div",{style:{marginBottom:"4px"},children:[o.jsx("span",{style:a,children:"Price:"}),o.jsxs("span",{style:g,children:[b," ",r.price.toFixed(2)]})]}),o.jsxs("div",{style:u,children:["Status: ",S]})]})})});Ct.displayName="SeatTooltip";const Ut=({config:n,configUrl:i,floorId:d,onFloorChange:r,reservedSeats:b=[],unavailableSeats:S=[],selectedSeats:x,onSeatSelect:v,onSeatDeselect:y,onSelectionChange:a,colorOverrides:s,showTooltip:g=!0,zoomEnabled:u=!0,className:M="",onConfigLoad:C,onError:R,showFloorSelector:T,floorSelectorPosition:V="top-left",floorSelectorClassName:_,showAllFloorsOption:G=!0,allFloorsLabel:U="All",fitToView:P=!0,fitPadding:W=40,showZoomControls:ot=!0,zoomControlsPosition:st="bottom-right",zoomControlsClassName:jt,maxZoom:I=3,zoomStep:Z=.25,touchEnabled:Mt=!0})=>{const it=e.useRef(null),ut=e.useRef(null),w=gt(ut),[X,ht]=e.useState(new Set),[j,A]=e.useState(1),[k,D]=e.useState({x:0,y:0}),[kt,Rt]=e.useState(null),[Et,It]=e.useState(1),K=e.useRef({width:0,height:0}),[B,dt]=e.useState({visible:!1,x:0,y:0,seat:null,state:"available"}),{config:Nt,loading:Lt,error:z}=pt(i),l=n||Nt,rt=d!==void 0,E=rt?d||null:kt,J=x!==void 0,Dt=e.useCallback(t=>{rt||Rt(t),r?.(t)},[rt,r]),ct=l?.floors||[],Tt=T!==void 0?T:ct.length>1,Q=e.useMemo(()=>l?{...l.colors,...s}:{...mt,...s},[l,s]),Y=e.useMemo(()=>{if(!l)return[];let t=l.seats.filter(c=>c.state!=="hidden");return E&&(t=t.filter(c=>c.floorId===E||!c.floorId&&E==="floor_default")),t},[l,E]),tt=e.useMemo(()=>l?.stages?E?l.stages.filter(t=>t.floorId===E||!t.floorId&&E==="floor_default"):l.stages:[],[l,E]),N=e.useMemo(()=>{if(!l||Y.length===0&&tt.length===0)return null;const t=12;let c=1/0,f=1/0,h=-1/0,p=-1/0;return Y.forEach(m=>{c=Math.min(c,m.position.x-t),f=Math.min(f,m.position.y-t),h=Math.max(h,m.position.x+t),p=Math.max(p,m.position.y+t)}),tt.forEach(m=>{c=Math.min(c,m.position.x),f=Math.min(f,m.position.y),h=Math.max(h,m.position.x+(m.config?.width||200)),p=Math.max(p,m.position.y+(m.config?.height||100))}),{minX:c,minY:f,maxX:h,maxY:p,width:h-c,height:p-f}},[l,Y,tt]);e.useEffect(()=>{if(!P||!l||!N||w.width===0||w.height===0)return;const t=Math.abs(w.width-K.current.width),c=Math.abs(w.height-K.current.height);if(!(K.current.width===0)&&t<10&&c<10)return;K.current=w;const h=w.width,p=w.height,m=h-W*2,q=p-W*2,et=m/N.width,lt=q/N.height,nt=Math.min(et,lt,I),Ht=N.minX+N.width/2,Ot=N.minY+N.height/2,qt=h/2,Vt=p/2,_t=qt-Ht*nt,Gt=Vt-Ot*nt;A(nt),D({x:_t,y:Gt}),It(nt)},[P,l,N,W,I,w,E]);const $=e.useMemo(()=>{const t=new Set(b),c=new Set(S);return{reserved:t,unavailable:c}},[b,S]),at=e.useMemo(()=>x?new Set(x):null,[x]),H=e.useCallback(t=>{const c=t.id,f=t.seatNumber||"";return $.unavailable.has(c)||$.unavailable.has(f)?"unavailable":$.reserved.has(c)||$.reserved.has(f)?"reserved":X.has(c)?"selected":t.state},[$,X]);e.useEffect(()=>{l&&C&&C(l)},[l,C]),e.useEffect(()=>{z&&R&&R(z)},[z,R]),e.useEffect(()=>{J&&at&&ht(at)},[J,at]);const Xt=e.useCallback(t=>{const c=H(t);if(c!=="available"&&c!=="selected")return;const f=X.has(t.id);J||ht(h=>{const p=new Set(h);return f?p.delete(t.id):p.add(t.id),p}),f?y?.(t):(v?.(t),v||console.log("Seat selected:",t))},[H,X,J,v,y]),O=e.useMemo(()=>l?Y.filter(t=>X.has(t.id)):[],[Y,X]);e.useEffect(()=>{a?.(O)},[O,a]);const F=Et,Yt=e.useCallback(()=>{if(!u)return;const t=Math.min(j+Z,I);if(t!==j){const c=w.width||l?.canvas.width||800,f=w.height||l?.canvas.height||600,h=c/2,p=f/2,m={x:(h-k.x)/j,y:(p-k.y)/j};A(t),D({x:h-m.x*t,y:p-m.y*t})}},[u,j,Z,I,w,l,k]),Ft=e.useCallback(()=>{if(!u)return;const t=Math.max(j-Z,F);if(t!==j){const c=w.width||l?.canvas.width||800,f=w.height||l?.canvas.height||600,h=c/2,p=f/2,m={x:(h-k.x)/j,y:(p-k.y)/j};A(t),D({x:h-m.x*t,y:p-m.y*t})}},[u,j,Z,F,w,l,k]),Pt=e.useCallback(t=>{D({x:t.target.x(),y:t.target.y()})},[]),Wt=e.useCallback(t=>{if(!u)return;t.evt.preventDefault();const c=it.current;if(!c)return;const f=c.scaleX(),h=c.getPointerPosition();if(!h)return;const p=1.1,m=t.evt.deltaY>0?f/p:f*p,q=Math.min(Math.max(m,F),I),et={x:(h.x-k.x)/f,y:(h.y-k.y)/f},lt={x:h.x-et.x*q,y:h.y-et.y*q};A(q),D(lt)},[u,k,F,I]);yt(it,{enabled:Mt&&u,minScale:F,maxScale:I,currentScale:j,currentPosition:k,onScaleChange:(t,c)=>{A(t),D(c)},onPositionChange:t=>{D(t)}});const At=e.useCallback((t,c)=>{if(!g)return;const f=c.target.getStage();if(!f)return;const h=f.getPointerPosition();if(!h)return;const p=f.container().getBoundingClientRect();dt({visible:!0,x:p.left+h.x,y:p.top+h.y,seat:t,state:H(t)})},[g,H]),Bt=e.useCallback(()=>{dt(t=>({...t,visible:!1}))},[]);if(Lt)return o.jsx("div",{className:`flex items-center justify-center h-full ${M}`,children:o.jsx("p",{children:"Loading seat map..."})});if(z)return o.jsx("div",{className:`flex items-center justify-center h-full ${M}`,children:o.jsxs("p",{className:"text-red-500",children:["Error loading seat map: ",z.message]})});if(!l)return o.jsx("div",{className:`flex items-center justify-center h-full ${M}`,children:o.jsx("p",{children:"No configuration provided"})});const zt=w.width||l.canvas.width,$t=w.height||l.canvas.height;return o.jsxs("div",{ref:ut,className:`relative ${M}`,style:{width:"100%",height:"100%"},children:[Tt&&ct.length>0&&o.jsx(vt,{floors:ct,currentFloorId:E,onFloorChange:Dt,showAllOption:G,allLabel:U,position:V,className:_}),o.jsxs(L.Stage,{ref:it,width:zt,height:$t,scaleX:j,scaleY:j,x:k.x,y:k.y,draggable:!0,onDragEnd:Pt,onWheel:Wt,style:{backgroundColor:l.canvas.backgroundColor,cursor:"grab"},children:[o.jsx(L.Layer,{listening:!1,children:tt.map(t=>o.jsx(St,{stage:t,stageColor:Q.stageColor},t.id))}),o.jsx(L.Layer,{children:Y.map(t=>o.jsx(bt,{seat:t,state:H(t),colors:Q,onClick:Xt,onMouseEnter:At,onMouseLeave:Bt},t.id))})]}),g&&o.jsx(Ct,{visible:B.visible,x:B.x,y:B.y,seat:B.seat,currency:Q.currency,state:B.state}),ot&&u&&o.jsx(wt,{scale:j,minScale:F,maxScale:I,onZoomIn:Yt,onZoomOut:Ft,position:st,className:jt}),O.length>0&&o.jsxs("div",{className:"absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg",children:[o.jsxs("h3",{className:"font-semibold mb-2",children:["Selected Seats (",O.length,")"]}),o.jsx("div",{className:"max-h-48 overflow-y-auto space-y-1",children:O.map(t=>o.jsxs("div",{className:"text-sm",children:[t.seatNumber,t.price&&` - ${Q.currency} ${t.price.toFixed(2)}`]},t.id))})]})]})};exports.DEFAULT_COLORS=mt;exports.SeatMapViewer=Ut;exports.useConfigFetcher=pt;exports.useContainerSize=gt;exports.useTouchGestures=yt;
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  import { jsx as h, jsxs as w } from "react/jsx-runtime";
2
- import { useState as L, useEffect as W, useRef as z, useCallback as I, useMemo as T, memo as U } from "react";
3
- import { Stage as Gt, Layer as gt, Group as Ut, Rect as mt, Text as Kt, Circle as Jt } from "react-konva";
4
- function Qt(e) {
5
- const [o, d] = L(null), [i, m] = L(!1), [b, p] = L(null), S = async () => {
2
+ import { useState as L, useEffect as T, useRef as z, useCallback as N, useMemo as E, memo as U } from "react";
3
+ import { Stage as Jt, Layer as mt, Group as Qt, Rect as St, Text as te, Circle as ee } from "react-konva";
4
+ function ne(e) {
5
+ const [o, d] = L(null), [i, m] = L(!1), [b, f] = L(null), v = async () => {
6
6
  if (e) {
7
- m(!0), p(null);
7
+ m(!0), f(null);
8
8
  try {
9
9
  const y = await fetch(e);
10
10
  if (!y.ok)
@@ -13,85 +13,85 @@ function Qt(e) {
13
13
  d(s);
14
14
  } catch (y) {
15
15
  const s = y instanceof Error ? y : new Error("Unknown error occurred");
16
- p(s), console.error("Failed to fetch seat map config:", s);
16
+ f(s), console.error("Failed to fetch seat map config:", s);
17
17
  } finally {
18
18
  m(!1);
19
19
  }
20
20
  }
21
21
  };
22
- return W(() => {
23
- S();
22
+ return T(() => {
23
+ v();
24
24
  }, [e]), {
25
25
  config: o,
26
26
  loading: i,
27
27
  error: b,
28
- refetch: S
28
+ refetch: v
29
29
  };
30
30
  }
31
- function te(e) {
31
+ function oe(e) {
32
32
  const [o, d] = L({ width: 0, height: 0 });
33
- return W(() => {
33
+ return T(() => {
34
34
  const i = e.current;
35
35
  if (!i) return;
36
36
  const { width: m, height: b } = i.getBoundingClientRect();
37
37
  m > 0 && b > 0 && d({ width: m, height: b });
38
- const p = new ResizeObserver((S) => {
39
- const y = S[0];
38
+ const f = new ResizeObserver((v) => {
39
+ const y = v[0];
40
40
  if (!y) return;
41
41
  const { width: s, height: n } = y.contentRect;
42
- s > 0 && n > 0 && d((a) => a.width === s && a.height === n ? a : { width: s, height: n });
42
+ s > 0 && n > 0 && d((g) => g.width === s && g.height === n ? g : { width: s, height: n });
43
43
  });
44
- return p.observe(i), () => {
45
- p.disconnect();
44
+ return f.observe(i), () => {
45
+ f.disconnect();
46
46
  };
47
47
  }, [e]), o;
48
48
  }
49
- function yt(e, o) {
49
+ function bt(e, o) {
50
50
  return Math.sqrt(Math.pow(o.x - e.x, 2) + Math.pow(o.y - e.y, 2));
51
51
  }
52
- function xt(e, o) {
52
+ function vt(e, o) {
53
53
  return {
54
54
  x: (e.x + o.x) / 2,
55
55
  y: (e.y + o.y) / 2
56
56
  };
57
57
  }
58
- function ee(e, o) {
58
+ function ie(e, o) {
59
59
  const d = z(null), i = z(null), m = z(1);
60
- W(() => {
60
+ T(() => {
61
61
  const b = e.current;
62
62
  if (!b || !o.enabled) return;
63
- const p = b.container(), S = (n) => {
63
+ const f = b.container(), v = (n) => {
64
64
  if (n.touches.length === 2) {
65
65
  n.preventDefault();
66
- const a = { x: n.touches[0].clientX, y: n.touches[0].clientY }, g = { x: n.touches[1].clientX, y: n.touches[1].clientY };
67
- d.current = yt(a, g), i.current = xt(a, g), m.current = o.currentScale;
66
+ const g = { x: n.touches[0].clientX, y: n.touches[0].clientY }, a = { x: n.touches[1].clientX, y: n.touches[1].clientY };
67
+ d.current = bt(g, a), i.current = vt(g, a), m.current = o.currentScale;
68
68
  }
69
69
  }, y = (n) => {
70
70
  if (n.touches.length !== 2) return;
71
71
  n.preventDefault();
72
- const a = { x: n.touches[0].clientX, y: n.touches[0].clientY }, g = { x: n.touches[1].clientX, y: n.touches[1].clientY }, N = yt(a, g), C = xt(a, g);
72
+ const g = { x: n.touches[0].clientX, y: n.touches[0].clientY }, a = { x: n.touches[1].clientX, y: n.touches[1].clientY }, k = bt(g, a), C = vt(g, a);
73
73
  if (d.current !== null && i.current !== null) {
74
- const D = N / d.current, $ = Math.min(
74
+ const D = k / d.current, P = Math.min(
75
75
  Math.max(o.currentScale * D, o.minScale),
76
76
  o.maxScale
77
- ), K = p.getBoundingClientRect(), J = C.x - K.left, Q = C.y - K.top, H = o.currentScale, P = {
78
- x: (J - o.currentPosition.x) / H,
79
- y: (Q - o.currentPosition.y) / H
80
- }, st = C.x - i.current.x, ct = C.y - i.current.y, at = {
81
- x: J - P.x * $ + st,
82
- y: Q - P.y * $ + ct
77
+ ), K = f.getBoundingClientRect(), J = C.x - K.left, Q = C.y - K.top, tt = o.currentScale, $ = {
78
+ x: (J - o.currentPosition.x) / tt,
79
+ y: (Q - o.currentPosition.y) / tt
80
+ }, H = C.x - i.current.x, at = C.y - i.current.y, lt = {
81
+ x: J - $.x * P + H,
82
+ y: Q - $.y * P + at
83
83
  };
84
- o.onScaleChange($, at), d.current = N, i.current = C;
84
+ o.onScaleChange(P, lt), d.current = k, i.current = C;
85
85
  }
86
86
  }, s = (n) => {
87
87
  n.touches.length < 2 && (d.current = null, i.current = null);
88
88
  };
89
- return p.addEventListener("touchstart", S, { passive: !1 }), p.addEventListener("touchmove", y, { passive: !1 }), p.addEventListener("touchend", s), () => {
90
- p.removeEventListener("touchstart", S), p.removeEventListener("touchmove", y), p.removeEventListener("touchend", s);
89
+ return f.addEventListener("touchstart", v, { passive: !1 }), f.addEventListener("touchmove", y, { passive: !1 }), f.addEventListener("touchend", s), () => {
90
+ f.removeEventListener("touchstart", v), f.removeEventListener("touchmove", y), f.removeEventListener("touchend", s);
91
91
  };
92
92
  }, [e, o]);
93
93
  }
94
- const ne = {
94
+ const re = {
95
95
  canvasBackground: "#1a1a1a",
96
96
  stageColor: "#808080",
97
97
  seatAvailable: "#2C2B30",
@@ -101,7 +101,7 @@ const ne = {
101
101
  seatHidden: "#4a4a4a",
102
102
  gridLines: "#404040",
103
103
  currency: "KD"
104
- }, bt = U(({ seat: e, state: o, colors: d, onClick: i, onMouseEnter: m, onMouseLeave: b }) => {
104
+ }, wt = U(({ seat: e, state: o, colors: d, onClick: i, onMouseEnter: m, onMouseLeave: b }) => {
105
105
  const y = {
106
106
  available: d.seatAvailable,
107
107
  reserved: d.seatReserved,
@@ -109,17 +109,17 @@ const ne = {
109
109
  unavailable: d.seatUnavailable,
110
110
  hidden: d.seatHidden
111
111
  // Hidden seats are filtered out, but included for type safety
112
- }[o], s = o === "available" || o === "selected", n = I(() => {
112
+ }[o], s = o === "available" || o === "selected", n = N(() => {
113
113
  s && i(e);
114
- }, [e, i, s]), a = I((C) => {
114
+ }, [e, i, s]), g = N((C) => {
115
115
  m(e, C);
116
116
  const D = C.target.getStage();
117
117
  D && s && (D.container().style.cursor = "pointer");
118
- }, [e, m, s]), g = I((C) => {
118
+ }, [e, m, s]), a = N((C) => {
119
119
  b();
120
120
  const D = C.target.getStage();
121
121
  D && (D.container().style.cursor = "grab");
122
- }, [b]), N = {
122
+ }, [b]), k = {
123
123
  x: e.position.x,
124
124
  y: e.position.y,
125
125
  fill: y,
@@ -127,19 +127,19 @@ const ne = {
127
127
  strokeWidth: 1,
128
128
  onClick: n,
129
129
  onTap: n,
130
- onMouseEnter: a,
131
- onMouseLeave: g
130
+ onMouseEnter: g,
131
+ onMouseLeave: a
132
132
  };
133
133
  return e.shape === "circle" ? /* @__PURE__ */ h(
134
- Jt,
134
+ ee,
135
135
  {
136
- ...N,
136
+ ...k,
137
137
  radius: 12
138
138
  }
139
139
  ) : /* @__PURE__ */ h(
140
- mt,
140
+ St,
141
141
  {
142
- ...N,
142
+ ...k,
143
143
  width: 24,
144
144
  height: 24,
145
145
  offsetX: 12,
@@ -148,10 +148,10 @@ const ne = {
148
148
  }
149
149
  );
150
150
  });
151
- bt.displayName = "ViewerSeat";
152
- const St = U(({ stage: e, stageColor: o }) => /* @__PURE__ */ w(Ut, { x: e.position.x, y: e.position.y, children: [
151
+ wt.displayName = "ViewerSeat";
152
+ const Ct = U(({ stage: e, stageColor: o }) => /* @__PURE__ */ w(Qt, { x: e.position.x, y: e.position.y, children: [
153
153
  /* @__PURE__ */ h(
154
- mt,
154
+ St,
155
155
  {
156
156
  width: e.config.width,
157
157
  height: e.config.height,
@@ -162,7 +162,7 @@ const St = U(({ stage: e, stageColor: o }) => /* @__PURE__ */ w(Ut, { x: e.posit
162
162
  }
163
163
  ),
164
164
  /* @__PURE__ */ h(
165
- Kt,
165
+ te,
166
166
  {
167
167
  text: e.config.label,
168
168
  x: 0,
@@ -177,18 +177,18 @@ const St = U(({ stage: e, stageColor: o }) => /* @__PURE__ */ w(Ut, { x: e.posit
177
177
  }
178
178
  )
179
179
  ] }));
180
- St.displayName = "ViewerStage";
181
- const vt = U(({
180
+ Ct.displayName = "ViewerStage";
181
+ const Mt = U(({
182
182
  floors: e,
183
183
  currentFloorId: o,
184
184
  onFloorChange: d,
185
185
  showAllOption: i,
186
186
  allLabel: m,
187
187
  position: b,
188
- className: p
188
+ className: f
189
189
  }) => {
190
- const S = T(
191
- () => [...e].sort((g, N) => g.order - N.order),
190
+ const v = E(
191
+ () => [...e].sort((a, k) => a.order - k.order),
192
192
  [e]
193
193
  ), s = {
194
194
  position: "absolute",
@@ -218,42 +218,42 @@ const vt = U(({
218
218
  transition: "all 0.2s ease",
219
219
  minHeight: "44px",
220
220
  touchAction: "manipulation"
221
- }, a = {
221
+ }, g = {
222
222
  ...n,
223
223
  backgroundColor: "#3A7DE5",
224
224
  borderColor: "#3A7DE5"
225
225
  };
226
- return /* @__PURE__ */ w("div", { className: p, style: s, children: [
226
+ return /* @__PURE__ */ w("div", { className: f, style: s, children: [
227
227
  i && /* @__PURE__ */ h(
228
228
  "button",
229
229
  {
230
230
  type: "button",
231
231
  onClick: () => d(null),
232
- style: o === null ? a : n,
232
+ style: o === null ? g : n,
233
233
  children: m
234
234
  }
235
235
  ),
236
- S.map((g) => /* @__PURE__ */ h(
236
+ v.map((a) => /* @__PURE__ */ h(
237
237
  "button",
238
238
  {
239
239
  type: "button",
240
- onClick: () => d(g.id),
241
- style: o === g.id ? a : n,
242
- children: g.name
240
+ onClick: () => d(a.id),
241
+ style: o === a.id ? g : n,
242
+ children: a.name
243
243
  },
244
- g.id
244
+ a.id
245
245
  ))
246
246
  ] });
247
247
  });
248
- vt.displayName = "FloorSelectorBar";
249
- const wt = U(({
248
+ Mt.displayName = "FloorSelectorBar";
249
+ const kt = U(({
250
250
  scale: e,
251
251
  minScale: o,
252
252
  maxScale: d,
253
253
  onZoomIn: i,
254
254
  onZoomOut: m,
255
255
  position: b,
256
- className: p
256
+ className: f
257
257
  }) => {
258
258
  const y = {
259
259
  position: "absolute",
@@ -292,15 +292,15 @@ const wt = U(({
292
292
  ...s,
293
293
  opacity: 0.4,
294
294
  cursor: "not-allowed"
295
- }, a = e < d, g = e > o;
296
- return /* @__PURE__ */ w("div", { className: p, style: y, children: [
295
+ }, g = e < d, a = e > o;
296
+ return /* @__PURE__ */ w("div", { className: f, style: y, children: [
297
297
  /* @__PURE__ */ h(
298
298
  "button",
299
299
  {
300
300
  type: "button",
301
301
  onClick: i,
302
- disabled: !a,
303
- style: a ? s : n,
302
+ disabled: !g,
303
+ style: g ? s : n,
304
304
  title: "Zoom In",
305
305
  children: "+"
306
306
  }
@@ -310,16 +310,16 @@ const wt = U(({
310
310
  {
311
311
  type: "button",
312
312
  onClick: m,
313
- disabled: !g,
314
- style: g ? s : n,
313
+ disabled: !a,
314
+ style: a ? s : n,
315
315
  title: "Zoom Out",
316
316
  children: "−"
317
317
  }
318
318
  )
319
319
  ] });
320
320
  });
321
- wt.displayName = "ZoomControls";
322
- const Ct = U(({
321
+ kt.displayName = "ZoomControls";
322
+ const It = U(({
323
323
  visible: e,
324
324
  x: o,
325
325
  y: d,
@@ -328,7 +328,7 @@ const Ct = U(({
328
328
  state: b
329
329
  }) => {
330
330
  if (!e || !i) return null;
331
- const p = i.seatNumber || (i.rowLabel && i.columnLabel ? `${i.rowLabel}-${i.columnLabel}` : "N/A"), S = {
331
+ const f = i.seatNumber || (i.rowLabel && i.columnLabel ? `${i.rowLabel}-${i.columnLabel}` : "N/A"), v = {
332
332
  position: "fixed",
333
333
  left: `${o + 15}px`,
334
334
  top: `${d + 15}px`,
@@ -348,294 +348,297 @@ const Ct = U(({
348
348
  marginRight: "4px"
349
349
  }, n = {
350
350
  fontWeight: 600
351
- }, a = {
351
+ }, g = {
352
352
  color: "#4ade80",
353
353
  fontWeight: 600
354
- }, g = {
354
+ }, a = {
355
355
  fontSize: "11px",
356
356
  color: "#6b7280",
357
357
  textTransform: "capitalize",
358
358
  marginTop: "4px"
359
359
  };
360
- return /* @__PURE__ */ h("div", { style: S, children: /* @__PURE__ */ w("div", { style: y, children: [
360
+ return /* @__PURE__ */ h("div", { style: v, children: /* @__PURE__ */ w("div", { style: y, children: [
361
361
  i.sectionName && /* @__PURE__ */ w("div", { style: { marginBottom: "4px" }, children: [
362
362
  /* @__PURE__ */ h("span", { style: s, children: "Section:" }),
363
363
  /* @__PURE__ */ h("span", { style: { ...n, color: "#3b82f6" }, children: i.sectionName })
364
364
  ] }),
365
365
  /* @__PURE__ */ w("div", { style: { marginBottom: "4px" }, children: [
366
366
  /* @__PURE__ */ h("span", { style: s, children: "Seat:" }),
367
- /* @__PURE__ */ h("span", { style: n, children: p })
367
+ /* @__PURE__ */ h("span", { style: n, children: f })
368
368
  ] }),
369
369
  i.price !== void 0 && i.price > 0 && /* @__PURE__ */ w("div", { style: { marginBottom: "4px" }, children: [
370
370
  /* @__PURE__ */ h("span", { style: s, children: "Price:" }),
371
- /* @__PURE__ */ w("span", { style: a, children: [
371
+ /* @__PURE__ */ w("span", { style: g, children: [
372
372
  m,
373
373
  " ",
374
374
  i.price.toFixed(2)
375
375
  ] })
376
376
  ] }),
377
- /* @__PURE__ */ w("div", { style: g, children: [
377
+ /* @__PURE__ */ w("div", { style: a, children: [
378
378
  "Status: ",
379
379
  b
380
380
  ] })
381
381
  ] }) });
382
382
  });
383
- Ct.displayName = "SeatTooltip";
384
- const se = ({
383
+ It.displayName = "SeatTooltip";
384
+ const le = ({
385
385
  config: e,
386
386
  configUrl: o,
387
387
  floorId: d,
388
388
  onFloorChange: i,
389
389
  reservedSeats: m = [],
390
390
  unavailableSeats: b = [],
391
- onSeatSelect: p,
392
- onSeatDeselect: S,
393
- onSelectionChange: y,
394
- colorOverrides: s,
395
- showTooltip: n = !0,
391
+ selectedSeats: f,
392
+ onSeatSelect: v,
393
+ onSeatDeselect: y,
394
+ onSelectionChange: s,
395
+ colorOverrides: n,
396
+ showTooltip: g = !0,
396
397
  zoomEnabled: a = !0,
397
- className: g = "",
398
- onConfigLoad: N,
399
- onError: C,
398
+ className: k = "",
399
+ onConfigLoad: C,
400
+ onError: D,
400
401
  // Floor selector props
401
- showFloorSelector: D,
402
- floorSelectorPosition: $ = "top-left",
403
- floorSelectorClassName: K,
404
- showAllFloorsOption: J = !0,
405
- allFloorsLabel: Q = "All",
406
- fitToView: H = !0,
407
- fitPadding: P = 40,
402
+ showFloorSelector: P,
403
+ floorSelectorPosition: K = "top-left",
404
+ floorSelectorClassName: J,
405
+ showAllFloorsOption: Q = !0,
406
+ allFloorsLabel: tt = "All",
407
+ fitToView: $ = !0,
408
+ fitPadding: H = 40,
408
409
  // Zoom controls
409
- showZoomControls: st = !0,
410
- zoomControlsPosition: ct = "bottom-right",
411
- zoomControlsClassName: at,
410
+ showZoomControls: at = !0,
411
+ zoomControlsPosition: lt = "bottom-right",
412
+ zoomControlsClassName: Nt,
412
413
  maxZoom: X = 3,
413
- zoomStep: tt = 0.25,
414
+ zoomStep: et = 0.25,
414
415
  // Touch gestures
415
- touchEnabled: Mt = !0
416
+ touchEnabled: Dt = !0
416
417
  }) => {
417
- const lt = z(null), ft = z(null), v = te(ft), [B, kt] = L(/* @__PURE__ */ new Set()), [M, j] = L(1), [k, E] = L({ x: 0, y: 0 }), [It, Nt] = L(null), [Dt, Rt] = L(1), et = z({ width: 0, height: 0 }), [O, pt] = L({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: Lt, loading: Xt, error: V } = Qt(o), c = e || Lt, ht = d !== void 0, R = ht ? d || null : It, Yt = I((t) => {
418
- ht || Nt(t), i?.(t);
419
- }, [ht, i]), dt = c?.floors || [], Et = D !== void 0 ? D : dt.length > 1, nt = T(
420
- () => c ? { ...c.colors, ...s } : { ...ne, ...s },
421
- [c, s]
422
- ), F = T(() => {
418
+ const ht = z(null), gt = z(null), S = oe(gt), [B, yt] = L(/* @__PURE__ */ new Set()), [M, j] = L(1), [I, W] = L({ x: 0, y: 0 }), [Rt, Lt] = L(null), [Xt, Yt] = L(1), nt = z({ width: 0, height: 0 }), [O, xt] = L({ visible: !1, x: 0, y: 0, seat: null, state: "available" }), { config: Et, loading: Tt, error: V } = ne(o), c = e || Et, dt = d !== void 0, R = dt ? d || null : Rt, ot = f !== void 0, Wt = N((t) => {
419
+ dt || Lt(t), i?.(t);
420
+ }, [dt, i]), ut = c?.floors || [], Pt = P !== void 0 ? P : ut.length > 1, it = E(
421
+ () => c ? { ...c.colors, ...n } : { ...re, ...n },
422
+ [c, n]
423
+ ), F = E(() => {
423
424
  if (!c) return [];
424
425
  let t = c.seats.filter((r) => r.state !== "hidden");
425
426
  return R && (t = t.filter(
426
427
  (r) => r.floorId === R || !r.floorId && R === "floor_default"
427
428
  )), t;
428
- }, [c, R]), ot = T(() => c?.stages ? R ? c.stages.filter(
429
+ }, [c, R]), rt = E(() => c?.stages ? R ? c.stages.filter(
429
430
  (t) => t.floorId === R || !t.floorId && R === "floor_default"
430
- ) : c.stages : [], [c, R]), Y = T(() => {
431
- if (!c || F.length === 0 && ot.length === 0)
431
+ ) : c.stages : [], [c, R]), Y = E(() => {
432
+ if (!c || F.length === 0 && rt.length === 0)
432
433
  return null;
433
434
  const t = 12;
434
- let r = 1 / 0, u = 1 / 0, l = -1 / 0, f = -1 / 0;
435
+ let r = 1 / 0, u = 1 / 0, l = -1 / 0, p = -1 / 0;
435
436
  return F.forEach((x) => {
436
- r = Math.min(r, x.position.x - t), u = Math.min(u, x.position.y - t), l = Math.max(l, x.position.x + t), f = Math.max(f, x.position.y + t);
437
- }), ot.forEach((x) => {
438
- r = Math.min(r, x.position.x), u = Math.min(u, x.position.y), l = Math.max(l, x.position.x + (x.config?.width || 200)), f = Math.max(f, x.position.y + (x.config?.height || 100));
439
- }), { minX: r, minY: u, maxX: l, maxY: f, width: l - r, height: f - u };
440
- }, [c, F, ot]);
441
- W(() => {
442
- if (!H || !c || !Y || v.width === 0 || v.height === 0) return;
443
- const t = Math.abs(v.width - et.current.width), r = Math.abs(v.height - et.current.height);
444
- if (!(et.current.width === 0) && t < 10 && r < 10) return;
445
- et.current = v;
446
- const l = v.width, f = v.height, x = l - P * 2, G = f - P * 2, it = x / Y.width, ut = G / Y.height, rt = Math.min(it, ut, X), jt = Y.minX + Y.width / 2, Ot = Y.minY + Y.height / 2, Vt = l / 2, Zt = f / 2, _t = Vt - jt * rt, qt = Zt - Ot * rt;
447
- j(rt), E({ x: _t, y: qt }), Rt(rt);
448
- }, [H, c, Y, P, X, v, R]);
449
- const Z = T(() => {
437
+ r = Math.min(r, x.position.x - t), u = Math.min(u, x.position.y - t), l = Math.max(l, x.position.x + t), p = Math.max(p, x.position.y + t);
438
+ }), rt.forEach((x) => {
439
+ r = Math.min(r, x.position.x), u = Math.min(u, x.position.y), l = Math.max(l, x.position.x + (x.config?.width || 200)), p = Math.max(p, x.position.y + (x.config?.height || 100));
440
+ }), { minX: r, minY: u, maxX: l, maxY: p, width: l - r, height: p - u };
441
+ }, [c, F, rt]);
442
+ T(() => {
443
+ if (!$ || !c || !Y || S.width === 0 || S.height === 0) return;
444
+ const t = Math.abs(S.width - nt.current.width), r = Math.abs(S.height - nt.current.height);
445
+ if (!(nt.current.width === 0) && t < 10 && r < 10) return;
446
+ nt.current = S;
447
+ const l = S.width, p = S.height, x = l - H * 2, G = p - H * 2, st = x / Y.width, pt = G / Y.height, ct = Math.min(st, pt, X), Zt = Y.minX + Y.width / 2, _t = Y.minY + Y.height / 2, qt = l / 2, Gt = p / 2, Ut = qt - Zt * ct, Kt = Gt - _t * ct;
448
+ j(ct), W({ x: Ut, y: Kt }), Yt(ct);
449
+ }, [$, c, Y, H, X, S, R]);
450
+ const Z = E(() => {
450
451
  const t = new Set(m), r = new Set(b);
451
452
  return { reserved: t, unavailable: r };
452
- }, [m, b]), _ = I((t) => {
453
+ }, [m, b]), ft = E(() => f ? new Set(f) : null, [f]), _ = N((t) => {
453
454
  const r = t.id, u = t.seatNumber || "";
454
455
  return Z.unavailable.has(r) || Z.unavailable.has(u) ? "unavailable" : Z.reserved.has(r) || Z.reserved.has(u) ? "reserved" : B.has(r) ? "selected" : t.state;
455
456
  }, [Z, B]);
456
- W(() => {
457
- c && N && N(c);
458
- }, [c, N]), W(() => {
459
- V && C && C(V);
460
- }, [V, C]);
461
- const Tt = I((t) => {
457
+ T(() => {
458
+ c && C && C(c);
459
+ }, [c, C]), T(() => {
460
+ V && D && D(V);
461
+ }, [V, D]), T(() => {
462
+ ot && ft && yt(ft);
463
+ }, [ot, ft]);
464
+ const Bt = N((t) => {
462
465
  const r = _(t);
463
466
  if (r !== "available" && r !== "selected")
464
467
  return;
465
468
  const u = B.has(t.id);
466
- kt((l) => {
467
- const f = new Set(l);
468
- return u ? f.delete(t.id) : f.add(t.id), f;
469
- }), u ? S?.(t) : (p?.(t), p || console.log("Seat selected:", t));
470
- }, [_, B, p, S]), q = T(() => c ? F.filter((t) => B.has(t.id)) : [], [F, B]);
471
- W(() => {
472
- y?.(q);
473
- }, [q, y]);
474
- const A = Dt, Wt = I(() => {
469
+ ot || yt((l) => {
470
+ const p = new Set(l);
471
+ return u ? p.delete(t.id) : p.add(t.id), p;
472
+ }), u ? y?.(t) : (v?.(t), v || console.log("Seat selected:", t));
473
+ }, [_, B, ot, v, y]), q = E(() => c ? F.filter((t) => B.has(t.id)) : [], [F, B]);
474
+ T(() => {
475
+ s?.(q);
476
+ }, [q, s]);
477
+ const A = Xt, Ft = N(() => {
475
478
  if (!a) return;
476
- const t = Math.min(M + tt, X);
479
+ const t = Math.min(M + et, X);
477
480
  if (t !== M) {
478
- const r = v.width || c?.canvas.width || 800, u = v.height || c?.canvas.height || 600, l = r / 2, f = u / 2, x = {
479
- x: (l - k.x) / M,
480
- y: (f - k.y) / M
481
+ const r = S.width || c?.canvas.width || 800, u = S.height || c?.canvas.height || 600, l = r / 2, p = u / 2, x = {
482
+ x: (l - I.x) / M,
483
+ y: (p - I.y) / M
481
484
  };
482
- j(t), E({
485
+ j(t), W({
483
486
  x: l - x.x * t,
484
- y: f - x.y * t
487
+ y: p - x.y * t
485
488
  });
486
489
  }
487
- }, [a, M, tt, X, v, c, k]), Pt = I(() => {
490
+ }, [a, M, et, X, S, c, I]), At = N(() => {
488
491
  if (!a) return;
489
- const t = Math.max(M - tt, A);
492
+ const t = Math.max(M - et, A);
490
493
  if (t !== M) {
491
- const r = v.width || c?.canvas.width || 800, u = v.height || c?.canvas.height || 600, l = r / 2, f = u / 2, x = {
492
- x: (l - k.x) / M,
493
- y: (f - k.y) / M
494
+ const r = S.width || c?.canvas.width || 800, u = S.height || c?.canvas.height || 600, l = r / 2, p = u / 2, x = {
495
+ x: (l - I.x) / M,
496
+ y: (p - I.y) / M
494
497
  };
495
- j(t), E({
498
+ j(t), W({
496
499
  x: l - x.x * t,
497
- y: f - x.y * t
500
+ y: p - x.y * t
498
501
  });
499
502
  }
500
- }, [a, M, tt, A, v, c, k]), Bt = I((t) => {
501
- E({
503
+ }, [a, M, et, A, S, c, I]), zt = N((t) => {
504
+ W({
502
505
  x: t.target.x(),
503
506
  y: t.target.y()
504
507
  });
505
- }, []), Ft = I((t) => {
508
+ }, []), $t = N((t) => {
506
509
  if (!a) return;
507
510
  t.evt.preventDefault();
508
- const r = lt.current;
511
+ const r = ht.current;
509
512
  if (!r) return;
510
513
  const u = r.scaleX(), l = r.getPointerPosition();
511
514
  if (!l) return;
512
- const f = 1.1, x = t.evt.deltaY > 0 ? u / f : u * f, G = Math.min(Math.max(x, A), X), it = {
513
- x: (l.x - k.x) / u,
514
- y: (l.y - k.y) / u
515
- }, ut = {
516
- x: l.x - it.x * G,
517
- y: l.y - it.y * G
515
+ const p = 1.1, x = t.evt.deltaY > 0 ? u / p : u * p, G = Math.min(Math.max(x, A), X), st = {
516
+ x: (l.x - I.x) / u,
517
+ y: (l.y - I.y) / u
518
+ }, pt = {
519
+ x: l.x - st.x * G,
520
+ y: l.y - st.y * G
518
521
  };
519
- j(G), E(ut);
520
- }, [a, k, A, X]);
521
- ee(lt, {
522
- enabled: Mt && a,
522
+ j(G), W(pt);
523
+ }, [a, I, A, X]);
524
+ ie(ht, {
525
+ enabled: Dt && a,
523
526
  minScale: A,
524
527
  maxScale: X,
525
528
  currentScale: M,
526
- currentPosition: k,
529
+ currentPosition: I,
527
530
  onScaleChange: (t, r) => {
528
- j(t), E(r);
531
+ j(t), W(r);
529
532
  },
530
533
  onPositionChange: (t) => {
531
- E(t);
534
+ W(t);
532
535
  }
533
536
  });
534
- const At = I((t, r) => {
535
- if (!n) return;
537
+ const Ht = N((t, r) => {
538
+ if (!g) return;
536
539
  const u = r.target.getStage();
537
540
  if (!u) return;
538
541
  const l = u.getPointerPosition();
539
542
  if (!l) return;
540
- const f = u.container().getBoundingClientRect();
541
- pt({
543
+ const p = u.container().getBoundingClientRect();
544
+ xt({
542
545
  visible: !0,
543
- x: f.left + l.x,
544
- y: f.top + l.y,
546
+ x: p.left + l.x,
547
+ y: p.top + l.y,
545
548
  seat: t,
546
549
  state: _(t)
547
550
  });
548
- }, [n, _]), zt = I(() => {
549
- pt((t) => ({ ...t, visible: !1 }));
551
+ }, [g, _]), jt = N(() => {
552
+ xt((t) => ({ ...t, visible: !1 }));
550
553
  }, []);
551
- if (Xt)
552
- return /* @__PURE__ */ h("div", { className: `flex items-center justify-center h-full ${g}`, children: /* @__PURE__ */ h("p", { children: "Loading seat map..." }) });
554
+ if (Tt)
555
+ return /* @__PURE__ */ h("div", { className: `flex items-center justify-center h-full ${k}`, children: /* @__PURE__ */ h("p", { children: "Loading seat map..." }) });
553
556
  if (V)
554
- return /* @__PURE__ */ h("div", { className: `flex items-center justify-center h-full ${g}`, children: /* @__PURE__ */ w("p", { className: "text-red-500", children: [
557
+ return /* @__PURE__ */ h("div", { className: `flex items-center justify-center h-full ${k}`, children: /* @__PURE__ */ w("p", { className: "text-red-500", children: [
555
558
  "Error loading seat map: ",
556
559
  V.message
557
560
  ] }) });
558
561
  if (!c)
559
- return /* @__PURE__ */ h("div", { className: `flex items-center justify-center h-full ${g}`, children: /* @__PURE__ */ h("p", { children: "No configuration provided" }) });
560
- const $t = v.width || c.canvas.width, Ht = v.height || c.canvas.height;
562
+ return /* @__PURE__ */ h("div", { className: `flex items-center justify-center h-full ${k}`, children: /* @__PURE__ */ h("p", { children: "No configuration provided" }) });
563
+ const Ot = S.width || c.canvas.width, Vt = S.height || c.canvas.height;
561
564
  return /* @__PURE__ */ w(
562
565
  "div",
563
566
  {
564
- ref: ft,
565
- className: `relative ${g}`,
567
+ ref: gt,
568
+ className: `relative ${k}`,
566
569
  style: { width: "100%", height: "100%" },
567
570
  children: [
568
- Et && dt.length > 0 && /* @__PURE__ */ h(
569
- vt,
571
+ Pt && ut.length > 0 && /* @__PURE__ */ h(
572
+ Mt,
570
573
  {
571
- floors: dt,
574
+ floors: ut,
572
575
  currentFloorId: R,
573
- onFloorChange: Yt,
574
- showAllOption: J,
575
- allLabel: Q,
576
- position: $,
577
- className: K
576
+ onFloorChange: Wt,
577
+ showAllOption: Q,
578
+ allLabel: tt,
579
+ position: K,
580
+ className: J
578
581
  }
579
582
  ),
580
583
  /* @__PURE__ */ w(
581
- Gt,
584
+ Jt,
582
585
  {
583
- ref: lt,
584
- width: $t,
585
- height: Ht,
586
+ ref: ht,
587
+ width: Ot,
588
+ height: Vt,
586
589
  scaleX: M,
587
590
  scaleY: M,
588
- x: k.x,
589
- y: k.y,
591
+ x: I.x,
592
+ y: I.y,
590
593
  draggable: !0,
591
- onDragEnd: Bt,
592
- onWheel: Ft,
594
+ onDragEnd: zt,
595
+ onWheel: $t,
593
596
  style: { backgroundColor: c.canvas.backgroundColor, cursor: "grab" },
594
597
  children: [
595
- /* @__PURE__ */ h(gt, { listening: !1, children: ot.map((t) => /* @__PURE__ */ h(
596
- St,
598
+ /* @__PURE__ */ h(mt, { listening: !1, children: rt.map((t) => /* @__PURE__ */ h(
599
+ Ct,
597
600
  {
598
601
  stage: t,
599
- stageColor: nt.stageColor
602
+ stageColor: it.stageColor
600
603
  },
601
604
  t.id
602
605
  )) }),
603
- /* @__PURE__ */ h(gt, { children: F.map((t) => /* @__PURE__ */ h(
604
- bt,
606
+ /* @__PURE__ */ h(mt, { children: F.map((t) => /* @__PURE__ */ h(
607
+ wt,
605
608
  {
606
609
  seat: t,
607
610
  state: _(t),
608
- colors: nt,
609
- onClick: Tt,
610
- onMouseEnter: At,
611
- onMouseLeave: zt
611
+ colors: it,
612
+ onClick: Bt,
613
+ onMouseEnter: Ht,
614
+ onMouseLeave: jt
612
615
  },
613
616
  t.id
614
617
  )) })
615
618
  ]
616
619
  }
617
620
  ),
618
- n && /* @__PURE__ */ h(
619
- Ct,
621
+ g && /* @__PURE__ */ h(
622
+ It,
620
623
  {
621
624
  visible: O.visible,
622
625
  x: O.x,
623
626
  y: O.y,
624
627
  seat: O.seat,
625
- currency: nt.currency,
628
+ currency: it.currency,
626
629
  state: O.state
627
630
  }
628
631
  ),
629
- st && a && /* @__PURE__ */ h(
630
- wt,
632
+ at && a && /* @__PURE__ */ h(
633
+ kt,
631
634
  {
632
635
  scale: M,
633
636
  minScale: A,
634
637
  maxScale: X,
635
- onZoomIn: Wt,
636
- onZoomOut: Pt,
637
- position: ct,
638
- className: at
638
+ onZoomIn: Ft,
639
+ onZoomOut: At,
640
+ position: lt,
641
+ className: Nt
639
642
  }
640
643
  ),
641
644
  q.length > 0 && /* @__PURE__ */ w("div", { className: "absolute top-4 right-4 bg-white dark:bg-gray-800 p-4 rounded shadow-lg", children: [
@@ -646,7 +649,7 @@ const se = ({
646
649
  ] }),
647
650
  /* @__PURE__ */ h("div", { className: "max-h-48 overflow-y-auto space-y-1", children: q.map((t) => /* @__PURE__ */ w("div", { className: "text-sm", children: [
648
651
  t.seatNumber,
649
- t.price && ` - ${nt.currency} ${t.price.toFixed(2)}`
652
+ t.price && ` - ${it.currency} ${t.price.toFixed(2)}`
650
653
  ] }, t.id)) })
651
654
  ] })
652
655
  ]
@@ -654,9 +657,9 @@ const se = ({
654
657
  );
655
658
  };
656
659
  export {
657
- ne as DEFAULT_COLORS,
658
- se as SeatMapViewer,
659
- Qt as useConfigFetcher,
660
- te as useContainerSize,
661
- ee as useTouchGestures
660
+ re as DEFAULT_COLORS,
661
+ le as SeatMapViewer,
662
+ ne as useConfigFetcher,
663
+ oe as useContainerSize,
664
+ ie as useTouchGestures
662
665
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zonetrix/viewer",
3
- "version": "2.5.0",
3
+ "version": "2.6.0",
4
4
  "type": "module",
5
5
  "description": "Lightweight React component for rendering interactive seat maps",
6
6
  "main": "./dist/index.js",