Skip to content

Commit

Permalink
Merge branch 'main' into hp/button-icons-for-detour-creation
Browse files Browse the repository at this point in the history
  • Loading branch information
hannahpurcell authored Oct 16, 2024
2 parents 6dfb9de + 829201a commit b0e22ac
Show file tree
Hide file tree
Showing 29 changed files with 790 additions and 1,033 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 @@ -13,7 +13,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 @@ -19,7 +19,7 @@ export const DetourFinishedPanel = ({
}: DetourFinishedPanelProps) => (
<Panel as="article">
<Panel.Header className="">
<h1 className="c-diversion-panel__h1 my-3">Share Detour Details</h1>
<h1 className="c-diversion-panel__h1 my-3">View Draft Detour</h1>
</Panel.Header>

<Panel.Body className="d-flex flex-column">
Expand All @@ -30,7 +30,7 @@ export const DetourFinishedPanel = ({
variant="outline-primary"
onClick={onNavigateBack}
>
<BsIcons.ArrowLeft /> Edit Detour
<BsIcons.ArrowLeft /> Edit
</Button>

<Form.Control
Expand Down
Original file line number Diff line number Diff line change
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
4 changes: 2 additions & 2 deletions assets/src/components/detours/diversionPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -427,9 +427,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 b0e22ac

Please sign in to comment.