diff --git a/packages/components/src/toast/mod.tsx b/packages/components/src/toast/mod.tsx index 980165b..ee6ebd5 100644 --- a/packages/components/src/toast/mod.tsx +++ b/packages/components/src/toast/mod.tsx @@ -15,15 +15,14 @@ type Positions = | 'botom right' type Variant = 'filled' | 'standard' | 'outlined' interface ToasterProps { - type: 'info' | 'success' | 'warning' | 'error' - message: string + type?: 'info' | 'success' | 'warning' | 'error' + message?: string position?: Positions variant?: Variant timeout?: number + open?: boolean } -interface ToasterState extends ToasterProps { - open: boolean -} +type ToasterState = ToasterProps const defaultState: ToasterState = { open: false, @@ -54,27 +53,27 @@ const Toaster: FC<{ anchor?: Positions; kind?: Variant }> = ({ anchor, kind }) = const pos = { vertical, horizontal } as SnackbarOrigin useEffect(() => { - const onOpen = (evt: CustomEvent) => { + const onToast = (evt: CustomEvent) => { setState(prev => ({ ...prev, ...evt.detail, - open: true + open: evt.detail.open ?? true })) } - window.addEventListener(EVENT_NAME, onOpen as EventListener) + window.addEventListener(EVENT_NAME, onToast as EventListener) return () => { - window.removeEventListener(EVENT_NAME, onOpen as EventListener) + window.removeEventListener(EVENT_NAME, onToast as EventListener) } }, []) return ( diff --git a/packages/ui/src/components/formItem.tsx b/packages/ui/src/components/formItem.tsx index afec3b6..2daefad 100644 --- a/packages/ui/src/components/formItem.tsx +++ b/packages/ui/src/components/formItem.tsx @@ -44,17 +44,6 @@ const getGap = ({ direction, gap }: LabelProps) => { return '8px' } -const getGrow = ({ direction, grow }: LabelProps) => { - if (typeof grow === 'number') { - return grow - } - - if (direction === 'vertical') { - return 0 - } - - return 1 -} const getJustifyContent = ({ direction, justifyContent }: LabelProps) => { if (justifyContent) { return justifyContent @@ -79,7 +68,6 @@ const Label = styled.label` } span:last-child { display: flex; - flex-grow: ${getGrow}; } ` diff --git a/packages/ui/src/home.tsx b/packages/ui/src/home.tsx index 46b9a09..384d777 100644 --- a/packages/ui/src/home.tsx +++ b/packages/ui/src/home.tsx @@ -69,9 +69,9 @@ const Home: FC = () => { refetchInterval: 10_000, onSuccess(data) { update({ type: 'predictions', value: data }) + dispatch({ type: 'timestamp', value: Date.now() }) // Reset vehicles based on changed predicted vehicles vehiclesDispatch({ type: 'reset' }) - dispatch({ type: 'timestamp', value: Date.now() }) } } ) @@ -90,10 +90,12 @@ const Home: FC = () => { onSuccess(data) { vehiclesDispatch({ type: 'set', value: data }) - if (!data.length) { + if (!data.filter(({ predictable }) => predictable).length) { toast({ type: 'info', - message: 'No vehicles running' + message: 'No vehicles on route.', + // Keep open until the user closes + timeout: undefined }) } } diff --git a/packages/ui/src/hooks/common.ts b/packages/ui/src/hooks/common.ts index 7405839..f538f40 100644 --- a/packages/ui/src/hooks/common.ts +++ b/packages/ui/src/hooks/common.ts @@ -52,4 +52,5 @@ class VehicleMarker extends Marker { } } +export const VEHICLE_PANE = 'busmap-vehicle-pane' export { VehicleMarker } diff --git a/packages/ui/src/hooks/useInitMap.ts b/packages/ui/src/hooks/useInitMap.ts index 9ab10b7..2d9c478 100644 --- a/packages/ui/src/hooks/useInitMap.ts +++ b/packages/ui/src/hooks/useInitMap.ts @@ -1,6 +1,8 @@ import { useEffect, useRef, useState } from 'react' import L from 'leaflet' +import { VEHICLE_PANE } from './common.js' + import { useGlobals } from '../globals.js' import type { Map, LayerGroup } from 'leaflet' @@ -19,6 +21,7 @@ const useInitMap = () => { mapRef.current = L.map(document.querySelector('main') as HTMLElement, { zoomControl: false }) + mapRef.current.createPane(VEHICLE_PANE).style.zIndex = '700' popupRef.current.setContent(selectionRef.current) popupRef.current.on('remove', () => { dispatch({ type: 'selected', value: undefined }) diff --git a/packages/ui/src/hooks/usePrevious.ts b/packages/ui/src/hooks/usePrevious.ts new file mode 100644 index 0000000..60c4936 --- /dev/null +++ b/packages/ui/src/hooks/usePrevious.ts @@ -0,0 +1,13 @@ +import { useRef, useEffect } from 'react' + +const usePrevious = (value: T) => { + const ref = useRef(value) + + useEffect(() => { + ref.current = value + }, [value]) + + return ref.current +} + +export { usePrevious } diff --git a/packages/ui/src/hooks/useVehiclesLayer.ts b/packages/ui/src/hooks/useVehiclesLayer.ts index 39b21ab..9a932ab 100644 --- a/packages/ui/src/hooks/useVehiclesLayer.ts +++ b/packages/ui/src/hooks/useVehiclesLayer.ts @@ -1,7 +1,7 @@ import { useEffect, useRef } from 'react' import L from 'leaflet' -import { VehicleMarker } from './common.js' +import { VehicleMarker, VEHICLE_PANE } from './common.js' import { useGlobals } from '../globals.js' import { useVehicles } from '../contexts/vehicles.js' @@ -236,7 +236,8 @@ const useVehiclesLayer = ({ vehiclesLayer }: UseVehiclesLayer) => { vehicle.directionId !== direction?.id }, { - icon + icon, + pane: VEHICLE_PANE } ) const popup = L.popup({ diff --git a/packages/ui/src/root.tsx b/packages/ui/src/root.tsx index ebb6012..70ec8ce 100644 --- a/packages/ui/src/root.tsx +++ b/packages/ui/src/root.tsx @@ -1,11 +1,18 @@ -import { Outlet } from 'react-router-dom' -import { Toaster } from '@busmap/components/toast' +import { useEffect } from 'react' +import { Outlet, useLocation } from 'react-router-dom' +import { Toaster, toast } from '@busmap/components/toast' import { Layout } from './layout.js' import { ErrorBoundary } from './components/errorBoundary.js' // TODO: Should fetch agencies here and set it in context const Root = () => { + const location = useLocation() + + useEffect(() => { + toast({ open: false }) + }, [location]) + return (