Skip to content

Commit

Permalink
feat(ts/components/vehicleMarker): implement shuttle colors
Browse files Browse the repository at this point in the history
  • Loading branch information
firestack committed Oct 17, 2024
2 parents 96a4f8f + a68ef2e commit d008df7
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 6 deletions.
19 changes: 19 additions & 0 deletions assets/css/map/markers/_vehicle_marker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@
path {
fill: inherit;
}

&.c-vehicle-marker--shuttle {
// Shuttle Colors
&.c-vehicle-marker--blue {
fill: var(--color-blue-line);
}
&.c-vehicle-marker--orange {
fill: var(--color-orange-line);
}
&.c-vehicle-marker--green {
fill: var(--color-green-line);
}
&.c-vehicle-marker--red {
fill: var(--color-red-line);
}
&.c-vehicle-marker--cr {
fill: var(--color-cr-line);
}
}
}

.c-vehicle-map--label {
Expand Down
47 changes: 43 additions & 4 deletions assets/src/components/map/markers/vehicleMarker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ import { LatLngExpression, Marker } from "leaflet"
import React, {
PropsWithChildren,
useContext,
useEffect,
useRef,
useState,
useEffect,
} from "react"

import { StateDispatchContext } from "../../../contexts/stateDispatchContext"
import { joinClasses } from "../../../helpers/dom"
import { vehicleLabel } from "../../../helpers/vehicleLabel"
import { statusClasses, drawnStatus } from "../../../models/vehicleStatus"

import {
shuttleVariantFromRunId,
ShuttleVariant,
} from "../../../models/shuttle"
import { drawnStatus, statusClasses } from "../../../models/vehicleStatus"
import { Vehicle } from "../../../realtime"
import { ReactMarker } from "../utilities/reactMarker"

Expand All @@ -24,6 +27,39 @@ interface VehicleMarkerProps extends PropsWithChildren {
onShouldShowPopupChange?: (newValue: boolean) => void
}

/**
* If the supplied {@linkcode vehicle} is a shuttle, returns
* classes to more specifically style shuttles matching certain conditions.
* For example, specific styles depending on Rapid Transit Line the shuttle is
* associated with.
*
* @param vehicle The vehicle to return styles for
* @returns Array of classes to add to a vehicle marker
*/
const stylesForShuttle = (vehicle: Vehicle) => {
// If this vehicle isn't a shuttle, return no styles
if (vehicle.isShuttle === false) { return [] }

// Otherwise return a generic shuttle class and any more
// specific styles for the shuttle.
const classFor = (variant: string) => `c-vehicle-marker--${variant}`
const shuttleClasses = ["c-vehicle-marker--shuttle"]
switch (vehicle.runId && shuttleVariantFromRunId(vehicle.runId)) {
case ShuttleVariant.Blue:
return shuttleClasses.concat(classFor("blue"))
case ShuttleVariant.CommuterRail:
return shuttleClasses.concat(classFor("cr"))
case ShuttleVariant.Green:
return shuttleClasses.concat(classFor("green"))
case ShuttleVariant.Orange:
return shuttleClasses.concat(classFor("orange"))
case ShuttleVariant.Red:
return shuttleClasses.concat(classFor("red"))
default:
return shuttleClasses
}
}

export const VehicleMarker = ({
children,
vehicle,
Expand Down Expand Up @@ -95,7 +131,10 @@ export const VehicleMarker = ({
}}
icon={
<svg
className="c-vehicle-map__icon"
className={joinClasses([
"c-vehicle-map__icon",
...stylesForShuttle(vehicle)
])}
height="24"
viewBox="0 0 24 24"
width="24"
Expand Down
35 changes: 34 additions & 1 deletion assets/src/models/shuttle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,37 @@
import { Vehicle } from "../realtime"
import { RunId, Vehicle } from "../realtime"

export enum ShuttleVariant {
// Rapid Transit Lines
Blue = "Blue",
Green = "Green",
Orange = "Orange",
Red = "Red",

// Other Shuttle Types
CommuterRail = "CR",
Special = "Special",
}

export const shuttleVariantFromRunId = (
runId: RunId
): ShuttleVariant | null => {
switch (runId) {
case "999-0501":
return ShuttleVariant.Blue
case "999-0502":
return ShuttleVariant.Green
case "999-0503":
return ShuttleVariant.Orange
case "999-0504":
return ShuttleVariant.Red
case "999-0505":
return ShuttleVariant.CommuterRail
case "999-0555":
return ShuttleVariant.Special
default:
return null
}
}

export const formattedRunNumber = ({ runId }: Vehicle): string => {
if (runId === null) {
Expand Down
66 changes: 65 additions & 1 deletion assets/tests/components/map/markers/vehicleMarker.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import "@testing-library/jest-dom/jest-globals"

import { VehicleMarker } from "../../../../src/components/map/markers/vehicleMarker"

import { vehicleFactory } from "../../../factories/vehicle"
import { shuttleFactory, vehicleFactory } from "../../../factories/vehicle"
import { MapContainer } from "react-leaflet"

const TestMap = ({ children }: PropsWithChildren): React.JSX.Element => (
Expand Down Expand Up @@ -38,4 +38,68 @@ describe("VehicleMarker", () => {
expect(container.querySelector(".c-vehicle-map__icon")).toBeInTheDocument()
expect(screen.getByText("101")).toBeInTheDocument()
})

describe.each([
{
runId: "999-0501",
specialClass: ".c-vehicle-marker--blue"
},
{
runId: "999-0502",
specialClass: ".c-vehicle-marker--green"
},
{
runId: "999-0503",
specialClass: ".c-vehicle-marker--orange"
},
{
runId: "999-0504",
specialClass: ".c-vehicle-marker--red"
},
{
runId: "999-0505",
specialClass: ".c-vehicle-marker--cr"
},
{
runId: "999-0555",
specialClass: null
},
{
runId: "101",
specialClass: null
},
])("when vehicle is shuttle with runId:`$runId`", ({ runId, specialClass }) => {
test("should render with shuttle class", () => {
const { container } = render(
<VehicleMarker
vehicle={shuttleFactory.build({
runId,
})}
isPrimary={true}
/>,
{
wrapper: TestMap
}
)

expect(container.querySelector(".c-vehicle-marker--shuttle")).toBeInTheDocument()

})

specialClass !== null && test(`should render with class \`${specialClass}\``, () => {
const { container } = render(
<VehicleMarker
vehicle={shuttleFactory.build({
runId,
})}
isPrimary={true}
/>,
{
wrapper: TestMap
}
)

expect(container.querySelector(specialClass)).toBeInTheDocument()
})
})
})

0 comments on commit d008df7

Please sign in to comment.