UNPKG

@expofp/floorplan

Version:

Interactive floor plan library for expos and events

344 lines • 13.9 kB
import { Box, Point } from '@expofp/geometry'; import type { RawPoiType } from '@expofp/schema'; import type { ReactNode } from 'react'; import type { Kiosk } from '../components/Kiosk/SetKiosk'; import { type Booth } from './BoothStore'; import type { Category } from './CategoryStore'; import { EventItem, type Track } from './EventStore'; import { Exhibitor } from './ExhibitorStore'; import type { FuzzySearchResult } from './FuzzySearchEngineStore'; import type RootStore from './RootStore'; import { Route } from './RouteStore'; import { SpeakerItem } from './SpeakerStore'; import type { BannerType, InterfaceAction, ListItem, ListType, MapSettings, OverlaySize, Visibility } from './types'; interface InterfaceMetadata { id: string; className: string; priority: number; isActive: () => boolean; additionalClasses?: () => string[]; searchBoxConfig?: () => { mode: string; title?: string; subtitle?: string; badge?: string | number; icon?: string; } | null; actions?: () => InterfaceAction[]; } /** What one zoom-in step multiplies the zoom factor by — the zoom button and the double-click. */ export declare const ZOOM_IN_FACTOR = 1.5; /** What one zoom-out step multiplies the zoom factor by. */ export declare const ZOOM_OUT_FACTOR = 0.66; export default class UIState { private readonly rootStore; private readonly interfaceMetadata; list: ListType; details: Booth | Exhibitor | Route | Category | EventItem | SpeakerItem | null; hoveredExhibitor: Exhibitor | null; hoveredBooth: Booth | null; zoomBy: number | null; rollReset: boolean; moveToBooths: Booth[] | null; moveToRect: Box | null; /** * Breathing room the pending `moveToRect` wants, as a fraction of the framing * region per side — the visible map less the side panel, in both renderers. * `null` leaves it to the adaptive 15%/25% rule, which both renderers apply. * Fit-to-screen sets 0: its rect is the framing itself, so padding it would * zoom past the authored viewbox. */ moveToRectPaddingPercent: number | null; moveToLocation: boolean; menu: boolean; searchFocused: boolean; searchClearMode: boolean; printingPdf: boolean; screenSize: Point; desiredOverlaySize?: OverlaySize; overlayShowsAll: boolean; centerMap: boolean; zoomAfTransformK: number; activeListIndex: number; devicePixelRatio: number; previewExhibitor: Exhibitor | null; wsStarted: boolean; canvasStarted: boolean; inIdle: boolean; modalActive: { share: boolean; }; galleryActive: boolean; hideOverlay: boolean; searchButtonsOverride: boolean | null; hideCookieConsent: boolean; hideHeaderLogo: boolean; hideLogoInBooth: boolean; disableBookmarked: boolean; hideLanguage: boolean; monochrome: boolean; heatmap: boolean; heatmapYah: boolean; rootElement: HTMLDivElement | null; debugCircles: { x: number; y: number; radius: number; color?: string; }[]; mapControlsHidden: boolean; floorsControlHidden: boolean; hideFreeOrDemo: boolean; freeBannerDismissed: boolean; currentBanner: BannerType; sceneDefReady: boolean; categoryFilterOpen: boolean; selectedCategoryFilters: Category[]; selectedPoiTypeFilters: RawPoiType[]; selectedTrack: Track | null; subButtonsVisible: boolean; searchBoxMode: 'search' | 'details' | 'interface'; searchBoxTitle: string; searchBoxSubtitle?: string; routeTitle?: string; routeDescription?: string; isMultiPointRoute: boolean; tourTitle?: string; tourDescription?: string; isMultiPointTour: boolean; pathwayOnlyMode: boolean; isOverlayScrolled: boolean; listScrollTop: number; listScrollItemId: string | number | null; listScrollIndex: number; private scrollPositions; private scrollItemIds; _customUIScale: number | null; private readonly searchFilterHeightPx; private readonly searchInputHeightPx; private readonly overlayUISizePx; private readonly overlayKioskSizePx; private readonly overlayMediumHeightRems; setSelectedCategoryFilters(categories: Category[]): void; resetCategoryFilter(): void; setSearchClearMode(value: boolean): void; setRouteTitle(title: string): void; setRouteDescription(description: string): void; setIsMultiPointRoute(isMulti: boolean): void; setTourTitle(title: string): void; setTourDescription(description: string): void; setIsMultiPointTour(isMulti: boolean): void; setPathwayOnlyMode(value: boolean): void; setMultiPointTourList(tourId: string): void; get activePathwayLayers(): string[]; get highlightedBooths(): ReadonlySet<string>; constructor(rootStore: RootStore); get rtl(): boolean; get noOverlay(): boolean; get overlayOnDemand(): boolean; get overlayHiddenNow(): boolean; get onBoothClick(): (e: import("../types.js").FloorPlanBoothClickEvent) => void; get onMarkerClick(): (e: import("../types.js").FloorPlanMarkerEvent) => void; get onBookmarkClick(): (e: import("../types.js").FloorPlanBookmarkClickEvent) => void; get onVisitedClick(): (e: import("../types.js").FloorPlanVisitedClickEvent) => void; get onCategoryClick(): (e: import("../types.js").FloorPlanCategory) => void; get onDirection(): (e: import("../types.js").FloorPlanDirectionEvent | null) => void; get onDetails(): (e: import("../types.js").FloorPlanDetailsEvent) => void; get onExhibitorCustomButtonClick(): (e: import("../types.js").FloorPlanCustomButtonEvent) => void; get onGetCoordsClick(): (e: import("../types.js").FloorPlanGetCoordsEvent) => void; get selectedExhibitor(): Exhibitor | null; get selectedBooth(): Booth | null; get selectedCategory(): Category | null; get selectedRoute(): Route | null; get selectedSpeaker(): SpeakerItem | null; get uiScale(): number; get isGuidedToursActive(): boolean; get getRouteNextFloor(): string | null; readonly headerHeightRem = 0; get headerHeightPx(): number; /** Only the width, so readers skip height-only changes such as the on-screen keyboard. */ get screenWidth(): number; get overlayPosition(): "bottom" | "left"; get overlayCollapsed(): boolean; get overlaySize(): OverlaySize | undefined; get overlayBottom(): boolean; get overlayLeft(): boolean; get overlayWidthPx(): number; /** * Height of the header logos bar in rems — the one source of truth. CSS * reads it as `--ws-height`, which `Layout` sets from {@link wsHeightCss}. */ readonly wsHeightRems: number; /** * The `--ws-height` value for the layout root: the bar height scaled by * `--ui-scale`, as the scss `rem()` would write it, or `0px` with no bar. */ get wsHeightCss(): string; /** * Rems to pixels, scaled by `--ui-scale` — the JS twin of the scss `rem()` * function. Plain `remsToPixels` ignores the scale. */ scaledRemsToPixels(rems: number): number; get wsOccupiedHeightPx(): number; get wsShown(): boolean; get wsDesktopPosition(): "bottom" | "top"; get wsPosition(): "bottom" | "top"; get responsiveClass(): string; get mapVisibleTop(): number; get mapVisibleBottom(): number; readonly mapVisibleStart = 0; get searchActionsHeightPx(): number; get shouldShowSearchButtons(): boolean; get shouldShowMobileToggle(): boolean; /** * How far up from the bottom of the map the mobile "List" button reaches, or 0 while it is * hidden. Mirrors the button's `bottom` and `height` in `MobileToggleButton.scss` (`@expofp/ui`); * keep the two in sync. */ get mobileToggleTopPx(): number; get mobileToggleIsListMode(): boolean; get canvasVisibleRectPx(): Box; get shouldShiftMapRect(): boolean | Category | EventItem | Exhibitor | Route | SpeakerItem | Booth | null; get hasAppliedFilters(): boolean; get canvasVisibleRectPt(): Box; get canvasSizePt(): Point; get shouldUseBackdrop(): boolean | undefined; forceDim: boolean; setForceDim(forceDim: boolean): void; get dimmed(): boolean; get defaultSearchItems(): ListItem[]; get searchItems(): ListItem[]; get searchList(): ListItem[]; get foundInDescription(): ListItem[]; get foundInDescriptionStruct(): Record<string, string>; get categoryFilteredSearchList(): ListItem[]; get fuzzySearchItems(): FuzzySearchResult<ListItem>[]; get listItems(): ListItem[]; get listBooths(): Set<Booth>; get selectedBooths(): Set<Booth>; get hoveredBooths(): Set<Booth>; get visibility(): Visibility; setVisibility(visibility: Visibility): void; toggleMapOverlay(): void; changeZoom(zoom: number): void; zoomIn(): void; zoomOut(): void; fitBounds(): void; get previewMode(): boolean; get viewerMode(): boolean; get selectedEventItem(): EventItem | null; /** * How the camera moves before a host says otherwise. * * Both views a plan is drawn in read these, so the plan opens at the same angle and takes the * same time to get there whichever view is showing. */ get defaultMapSettings(): MapSettings; mapSettings: MapSettings; setMapSettings(settings: MapSettings): void; resetMapSettings(): void; /** * How far the camera may tilt back from top down, in degrees. * * MapLibre's own default, which both views are held to, so the plan tilts the same amount in * either one. Not a map setting, because a host has no reason to raise or lower it. */ readonly maxPitch = 60; /** Whether a pitch change eases rather than cuts. Both views read it. */ animatePitch: boolean; /** * Whether the venue shows its plan in 3D, which is its `allow3dView` flag and nothing else. * * `MaplibreStore` picks the first view mode from it, and the tilt gesture below hangs off it, so * a venue that never allows a tilted plan cannot be tilted by hand either. * * `hide3dMapDefault` is deliberately not read here. It asks for the flat view on load, which is a * starting camera rather than a venue without 3D, and narrowing this by it takes the tilt gesture * away from a venue that allows one. * * A plain getter, not a computed: the flag is frozen config with nothing to observe, and the map * store reads this from its own constructor. */ get is3DView(): boolean; /** * Whether the user may tilt the plan by hand. * * The gesture only, exactly as `rollEnabled` is: a camera command still tilts the plan whatever * this says, in either view, so a host may open the plan at an angle with the gesture off. The * venue decides first through `is3DView`, and the `pitch` map parameter a host may pass * through the URL narrows it further. * * `keepAlive`, because `defaultMapSettings` reads it from the constructor, where there is no * reaction to observe it and the store is configured with `computedRequiresReaction`. */ get pitchEnabled(): boolean; /** * Whether the user may turn the plan: the venue's own setting, narrowed by the `roll` map * parameter a host may pass through the URL. */ get rollEnabled(): boolean; get baseQRCodeUrl(): string; get viewMapOnPhoneQRCodeUrl(): string; get routeQRCodeUrl(): string; get isFeaturedExhibitorActive(): boolean; get activeInterfaceData(): InterfaceMetadata | null; /** Id of the screen the search box heads — lets custom CSS target one header. */ get activeInterfaceId(): string | undefined; get searchBoxConfig(): { mode: string; title?: string; subtitle?: string; badge?: string | number; icon?: string; }; get searchBoxActions(): InterfaceAction[]; get overlayInterfaceClasses(): string[]; get isOverlayOpen(): boolean; setOverlayScrolled(isScrolled: boolean): void; setListScrollTop(listType: string, scrollTop: number): void; setListScrollItemId(listType: string, itemId: string | number): void; getListScrollTop(listType: string): number; getListScrollItemId(listType: string): string | number | null; clearListScroll(listType: string): void; get bannerType(): BannerType; setCurrentBanner(banner: BannerType): void; forceShowDetails: boolean; setForceShowDetails(flag: boolean): void; get showRouteInstantly(): boolean; buildRoute: boolean; startBuildRoute(): void; globalErrorMessages: { title: string; body?: ReactNode; }[]; setGlobalErrorMessage(message: { title: string; body?: ReactNode; }): void; popGlobalErrorMessage(): void; private initializeUIScale; minUIScale: number; maxUIScale: number; setUIScale(scale: number | undefined, saveToStorage?: boolean): void; /** * Applies the UI scale a kiosk carries. Not on a phone: kiosk mode stays off there (see `kiosk`), * and its scale with it. */ setKioskUIScale(scale: number | undefined, saveToStorage: boolean): void; resetUIScale(): void; /** Drops a scale applied without saving, back to the stored one (or the default). */ restoreUIScale(): void; private kioskEnabled; /** * Kiosk mode. Never on for a phone ({@link isPhone}), whichever writer asks for it. A phone still * shows the kiosk's marker, which follows `kioskData`. */ get kiosk(): boolean; set kiosk(enabled: boolean); setKioskModeEnabled: boolean; enableSetKioskMode(enable: boolean): void; kioskData: Kiosk | null; setKioskData(kioskData: Kiosk | null): void; } export {}; //# sourceMappingURL=UIState.d.ts.map