Skip to content

Commit

Permalink
Merge branch 'main' into hp/update-copy-details
Browse files Browse the repository at this point in the history
  • Loading branch information
hannahpurcell authored Oct 16, 2024
2 parents 71b81e6 + 493e088 commit b0d3ffa
Show file tree
Hide file tree
Showing 31 changed files with 867 additions and 1,049 deletions.
5 changes: 4 additions & 1 deletion assets/src/components/detours/detourPanelComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ export const MissedStops = ({ missedStops }: MissedStopsProps) => (
{missedStops && (
<section className="pb-3">
<h2 className="c-diversion-panel__h2">
Missed Stops <Badge bg="missed-stop">{missedStops.length}</Badge>
Missed Stops
<Badge pill bg="missed-stop" className="ps-2 fs-4">
{missedStops.length}
</Badge>
</h2>
<ListGroup as="ul">
{uniqBy(missedStops, (stop) => stop.id).map((missedStop) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const DetourFinishedPanel = ({
}: DetourFinishedPanelProps) => (
<Panel as="article" className="c-diversion-panel">
<Panel.Header className="d-inline-flex justify-content-between">
<h1 className="c-diversion-panel__h1 my-3">Share Detour Details</h1>
<h1 className="c-diversion-panel__h1 my-3">View Draft Detour</h1>
<CopyButton detourText={detourText} />
</Panel.Header>

Expand All @@ -32,7 +32,7 @@ export const DetourFinishedPanel = ({
variant="outline-primary"
onClick={onNavigateBack}
>
<BsIcons.ArrowLeft /> Edit Detour
<BsIcons.ArrowLeft /> Edit
</Button>

<Form.Control
Expand All @@ -49,11 +49,11 @@ export const DetourFinishedPanel = ({
<Panel.Body.Footer className="d-flex flex-column">
{onActivateDetour && (
<Button
className="m-3 flex-grow-1"
variant="missed-stop"
className="m-3 flex-grow-1 icon-link justify-content-center"
onClick={onActivateDetour}
>
Activate Detour
<BsIcons.Power />
Start Detour
</Button>
)}
</Panel.Body.Footer>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
RoutePatternId,
} from "../../../schedule"
import RoutePropertiesCard from "../../mapPage/routePropertiesCard"
import { Brush } from "../../../helpers/bsIcons"

interface SelectedRouteInfoWithRoutePatterns {
selectedRoute: Route
Expand Down Expand Up @@ -142,7 +143,11 @@ export const DetourRouteSelectionPanel = ({
</Panel.Body.ScrollArea>

<Panel.Body.Footer className="d-flex">
<Button className="m-3 flex-grow-1" onClick={onConfirm}>
<Button
className="m-3 flex-grow-1 icon-link justify-content-center"
onClick={onConfirm}
>
<Brush />
Start drawing detour
</Button>
</Panel.Body.Footer>
Expand Down
12 changes: 8 additions & 4 deletions assets/src/components/detours/detourPanels/drawDetourPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DetourShape } from "../../../models/detour"
import { Button, ListGroup } from "react-bootstrap"
import { Panel } from "../diversionPage"
import { Stop } from "../../../schedule"
import { ArrowLeft } from "../../../helpers/bsIcons"
import { ArrowLeft, CardChecklist } from "../../../helpers/bsIcons"
import { AffectedRoute, MissedStops } from "../detourPanelComponents"

export interface DrawDetourPanelProps {
Expand Down Expand Up @@ -31,7 +31,7 @@ export const DrawDetourPanel = ({
}: DrawDetourPanelProps) => (
<Panel as="article" className="c-diversion-panel">
<Panel.Header>
<h1 className="c-diversion-panel__h1 my-3">Create Detour</h1>
<h1 className="c-diversion-panel__h1 my-3">Draw Detour</h1>
</Panel.Header>

<Panel.Body className="d-flex flex-column">
Expand Down Expand Up @@ -77,8 +77,12 @@ export const DrawDetourPanel = ({
</Panel.Body.ScrollArea>

<Panel.Body.Footer hidden={!detourFinished}>
<Button className="flex-grow-1 m-3" onClick={onReviewDetour}>
Review Detour
<Button
className="flex-grow-1 m-3 icon-link justify-content-center"
onClick={onReviewDetour}
>
<CardChecklist />
Review
</Button>
</Panel.Body.Footer>
</Panel.Body>
Expand Down
4 changes: 2 additions & 2 deletions assets/src/components/detours/diversionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -429,9 +429,9 @@ export const DiversionPage = ({
{useDetourProps.author}
</span>
</>
) : (
) : isMobile(displayType) ? (
<div className="flex-grow-1 fw-semibold text-center">Detours</div>
)}
) : null}
<CloseButton className="p-4" onClick={onClose} />
</header>

Expand Down
2 changes: 1 addition & 1 deletion assets/src/components/incomingBox.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useContext } from "react"
import { StateDispatchContext } from "../contexts/stateDispatchContext"
import vehicleLabel from "../helpers/vehicleLabel"
import { vehicleLabel } from "../helpers/vehicleLabel"
import { blockWaiverAlertStyle } from "../models/blockWaiver"
import { crowdingLabel, OccupancyStatus } from "../models/crowding"
import {
Expand Down
2 changes: 1 addition & 1 deletion assets/src/components/ladder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "tippy.js/dist/tippy.css"
import { StateDispatchContext } from "../contexts/stateDispatchContext"
import { flatten, partition } from "../helpers/array"
import { joinClasses } from "../helpers/dom"
import vehicleLabel from "../helpers/vehicleLabel"
import { vehicleLabel } from "../helpers/vehicleLabel"
import { blockWaiverAlertStyle } from "../models/blockWaiver"
import { crowdingLabel, OccupancyStatus } from "../models/crowding"
import {
Expand Down
65 changes: 58 additions & 7 deletions assets/src/components/map/utilities/reactDivIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,68 @@
import { useMemo } from "react"

import L, { DivIconOptions as LeafletDivIconOptions } from "leaflet"
import { DivIcon, DivIconOptions as LeafletDivIconOptions } from "leaflet"

// Prevent user from setting parameters we intend to provide
export type DivIconOptions = Omit<LeafletDivIconOptions, "html">

// Prevent useEffect from triggering by providing stable default reference
const defaultOptions = {}

// DefinitelyTyped definitions _seem_ to allow us to use a "real" class instead of `.extend`?
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/3923
// https://leafletjs.com/examples/extending/extending-1-classes.html
/**
* A Leaflet {@linkcode DivIcon} which uses a provided {@linkcode HTMLElement}
* as the marker element returned to leaflet when the associated Marker is added
* to the map.
*
* The provided {@linkcode HTMLElement} is a stable element that is created
* before the {@linkcode DivIcon} is added to a Map via a Marker. This is
* required so that the {@linkcode HTMLElement} reference can be created before
* the Marker and Icon are added to the `Map`
*/
class DivIconReactPortal extends DivIcon {
/**
* Stable element reference for React Portals.
*/
element: HTMLElement

constructor(element: HTMLElement, options?: DivIconOptions) {
super(options)
this.element = element
}

/**
* Overridden function which returns our stable {@linkcode HTMLElement}
* reference and configures the {@linkcode DivIconReactPortal.element}
* attributes according to Leaflet.
*
* ---
*
* {@linkcode _oldIcon} is the {@linkcode HTMLElement} reference that a
* Leaflet Marker stores between `onAdd` and `onRemove` calls.
* Because we _always_ want Leaflet to use our stable element reference,
* {@linkcode DivIconReactPortal.element} is always returned.
*/
createIcon(_oldIcon?: HTMLElement): HTMLElement {
this.setElementIconStyles()
return this.element
}

// The whole reason we have to recreate the `DivIcon` entirely is because we
// need to call `_setIconStyles` on the element, when the `DivIcon` `options`
// change. Pulling this out into it's own known function may allow us to
// avoid recreating the DivIcon entirely in the future, and instead update it
// when the `options` change.
setElementIconStyles() {
// We KNOW that this function exists, but the `DefinitelyTyped` definitions
// do not include it.
if ("_setIconStyles" in this && typeof this._setIconStyles === "function") {
this._setIconStyles(this.element, "icon")
}
}
}

/**
* Hook to create a `divIcon` compatible with {@link ReactDOM.createPortal}, by
* creating a stable {@link HTMLDivElement container} for React to use for
Expand All @@ -28,7 +83,7 @@ export function useReactDivIcon(options?: DivIconOptions) {
// To ensure that the `divIcon` updates when `opts` change
// regenerate the `divIcon` with the portal element and provided `opts`
const divIcon = useMemo(
() => L.divIcon({ ...opts, html: iconContainer }),
() => new DivIconReactPortal(iconContainer, opts),
[iconContainer, opts]
)

Expand All @@ -40,8 +95,4 @@ export function useReactDivIcon(options?: DivIconOptions) {

// Extend this function or add more parameters to `useReactDivIcon` to override
// portal element creation
const createPortalElement = () => {
const element = document.createElement("div")
element.classList.add("w-100", "h-100")
return element
}
const createPortalElement = () => document.createElement("div")
50 changes: 24 additions & 26 deletions assets/src/components/map/utilities/reactMarker.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React, { ReactNode } from "react"
import React, { forwardRef, ReactNode } from "react"
import { createPortal } from "react-dom"

import { Marker, MarkerProps } from "react-leaflet"

import { DivIconOptions, useReactDivIcon } from "./reactDivIcon"
import { Marker as LeafletMarker } from "leaflet"

/**
* Component Props for {@link ReactMarker}
Expand Down Expand Up @@ -31,30 +32,27 @@ export interface ReactMarkerProps extends Omit<MarkerProps, "icon"> {
*
* @param {ReactMarkerProps} props Component Props with {@link DivIconOptions `divIconSettings`}
*/
export const ReactMarker = ({
icon,
divIconSettings,
children,
...markerProps
}: ReactMarkerProps) => {
const { divIcon, iconContainer } = useReactDivIcon(divIconSettings)
export const ReactMarker = forwardRef<LeafletMarker<any>, ReactMarkerProps>(
({ icon, divIconSettings, children, ...markerProps }, ref) => {
const { divIcon, iconContainer } = useReactDivIcon(divIconSettings)

return (
<Marker {...(markerProps as MarkerProps)} icon={divIcon}>
<>
{
/*
React Events bubble up the React Virtual DOM,
so any Events to `icon` should bubble up to `Marker` first
*/
createPortal(icon, iconContainer)
}
return (
<Marker {...(markerProps as MarkerProps)} icon={divIcon} ref={ref}>
<>
{
/*
React Events bubble up the React Virtual DOM,
so any Events to `icon` should bubble up to `Marker` first
*/
createPortal(icon, iconContainer)
}

{
/* Provide children after portal so react has a stable virtual DOM reference */
children
}
</>
</Marker>
)
}
{
/* Provide children after portal so react has a stable virtual DOM reference */
children
}
</>
</Marker>
)
}
)
Loading

0 comments on commit b0d3ffa

Please sign in to comment.