Skip to content

Commit

Permalink
Initial fixes to tab order (#2370)
Browse files Browse the repository at this point in the history
* feat: reorganize wide nav

* feat: reorganize tablet nav

* feat: reorder other nav breakpoints

* fix: use fragment to make children maintain state across breakpoints

* fix: accessibility improvements to ladder page tabs

* fix: remove all of the individual route selectors from tab order

* refactor: turn StreetViewControl into a CustomControl

* feat: insertFirst option to CustomControl, use for StreetViewControl

* feat: allow street view on detour map

* fixup! feat: allow street view on detour map
  • Loading branch information
lemald authored Jan 25, 2024
1 parent 836a2f8 commit 2e6c52a
Show file tree
Hide file tree
Showing 12 changed files with 447 additions and 418 deletions.
2 changes: 1 addition & 1 deletion assets/src/components/detours/detourMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export const DetourMap = ({
undoDisabled,
onUndoLastWaypoint,
}: DetourMapProps) => (
<Map vehicles={[]}>
<Map vehicles={[]} allowStreetView>
<CustomControl position="topleft" className="leaflet-bar">
<Button
variant="primary"
Expand Down
3 changes: 2 additions & 1 deletion assets/src/components/ladderPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ const LadderTab = ({
}
}}
role="tab"
tabIndex={tab.isCurrentTab ? 0 : -1}
tabIndex={tab.isCurrentTab ? -1 : 0}
aria-selected={tab.isCurrentTab}
>
<div className="c-ladder-page__tab-contents">
<div
Expand Down
56 changes: 18 additions & 38 deletions assets/src/components/map/controls/StreetViewSwitch.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import Leaflet, { ControlOptions } from "leaflet"
import React, { useEffect, useId, useState } from "react"
import ReactDOM from "react-dom"
import { useMap, useMapEvents } from "react-leaflet"
import { joinClasses } from "../../../helpers/dom"
import { ControlOptions } from "leaflet"
import React, { useId } from "react"
import { useMapEvents } from "react-leaflet"
import { WalkingIcon } from "../../../helpers/icon"
import { streetViewUrl } from "../../../util/streetViewUrl"
import { CutoutOverlay } from "../../cutoutOverlay"
import { fullStoryEvent } from "../../../helpers/fullStory"
import { Form } from "react-bootstrap"
import { CustomControl } from "./customControl"
import { joinClasses } from "../../../helpers/dom"

export interface StreetViewControlProps extends ControlOptions {
streetViewEnabled: boolean
Expand All @@ -18,31 +18,6 @@ export const StreetViewControl = ({
streetViewEnabled,
setStreetViewEnabled,
}: StreetViewControlProps): JSX.Element | null => {
const map = useMap()
const portalParent = map
.getContainer()
.querySelector(".leaflet-control-container")
const [portalElement, setPortalElement] = useState<HTMLElement | null>(null)

useEffect(() => {
if (!portalParent || !portalElement) {
setPortalElement(document.createElement("div"))
}

if (portalParent && portalElement) {
portalElement.className = joinClasses([
"leaflet-control",
"leaflet-bar",
"c-street-view-switch",
"position-absolute",
])
portalParent.append(portalElement)
Leaflet.DomEvent.disableClickPropagation(portalElement)
}

return () => portalElement?.remove()
}, [portalElement, portalParent, setStreetViewEnabled])

useMapEvents(
streetViewEnabled
? {
Expand Down Expand Up @@ -75,14 +50,19 @@ export const StreetViewControl = ({

return (
<>
{portalElement &&
ReactDOM.createPortal(
<StreetViewSwitch
streetViewEnabled={streetViewEnabled}
setStreetViewEnabled={setStreetViewEnabled}
/>,
portalElement
)}
<CustomControl
className={joinClasses([
"leaflet-bar",
"c-street-view-switch",
"position-absolute",
])}
insertFirst
>
<StreetViewSwitch
streetViewEnabled={streetViewEnabled}
setStreetViewEnabled={setStreetViewEnabled}
/>
</CustomControl>
{streetViewEnabled && <CutoutOverlay.FollowMapMouseMove />}
</>
)
Expand Down
6 changes: 5 additions & 1 deletion assets/src/components/map/controls/customControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ export const CustomControl = ({
children,
className,
insertAfterSelector,
insertFirst,
}: ControlOptions & {
children: ReactNode
className?: string
insertAfterSelector?: string
insertFirst?: boolean
}): JSX.Element | null => {
const map = useMap()
const portalParent = map
Expand All @@ -50,14 +52,16 @@ export const CustomControl = ({
: null
if (elementToInsertAfter) {
elementToInsertAfter.after(portalElement)
} else if (insertFirst) {
portalParent.prepend(portalElement)
} else {
portalParent.append(portalElement)
}
Leaflet.DomEvent.disableClickPropagation(portalElement)
}

return () => portalElement?.remove()
}, [portalElement, portalParent, className, insertAfterSelector])
}, [portalElement, portalParent, className, insertAfterSelector, insertFirst])

return portalElement ? ReactDOM.createPortal(children, portalElement) : null
}
26 changes: 14 additions & 12 deletions assets/src/components/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ const Nav: React.FC<Props> = ({ children }) => {
case "mobile":
return (
<div className="l-nav--narrow">
<div className="l-nav__app-content">{children}</div>
<MobilePortraitNav isViewOpen={isViewOpen} />
<div className="l-nav__app-content">{children}</div>
</div>
)
case "mobile_landscape_tablet_portrait":
return (
<div className="l-nav--medium">
<div className="l-nav__app-content">{children}</div>
<div
className="l-nav__nav-bar l-nav__nav-bar--left"
hidden={isViewOpen}
Expand All @@ -41,34 +40,37 @@ const Nav: React.FC<Props> = ({ children }) => {
closePickerOnViewOpen={true}
/>
</div>
<div className="l-nav__app-content">{children}</div>
</div>
)
case "tablet":
return (
<div className="l-nav--medium">
<div className="l-nav__app-content">{children}</div>
<div className="l-nav__nav-bar l-nav__nav-bar--left">
<LeftNav
toggleMobileMenu={() => dispatch(toggleMobileMenu())}
defaultToCollapsed={true}
dispatcherFlag={readDispatcherFlag()}
/>
</div>
<div className="l-nav__app-content">{children}</div>
</div>
)
default:
return (
<div className="l-nav--wide">
<>
<div className="l-nav__nav-bar l-nav__nav-bar--top">
<TopNav />
</div>
<div className="l-nav__nav-bar l-nav__nav-bar--left">
<LeftNav
defaultToCollapsed={false}
dispatcherFlag={readDispatcherFlag()}
/>
</div>
</>
<div className="l-nav__app-content">{children}</div>
<div className="l-nav__nav-bar l-nav__nav-bar--top">
<TopNav />
</div>
<div className="l-nav__nav-bar l-nav__nav-bar--left">
<LeftNav
defaultToCollapsed={false}
dispatcherFlag={readDispatcherFlag()}
/>
</div>
</div>
)
}
Expand Down
2 changes: 2 additions & 0 deletions assets/src/components/routePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ const SelectedRouteButton = ({
<button
className="c-route-picker__selected-routes-button"
onClick={() => deselectRoute(routeId)}
tabIndex={-1}
>
{routeNameOrId(routeId, routes)}
<OldCloseIcon className="c-route-picker__selected-routes-button-icon" />
Expand Down Expand Up @@ -141,6 +142,7 @@ const RouteListButton = ({
<button
className="c-route-picker__route-list-button"
onClick={() => selectRoute(route.id)}
tabIndex={-1}
>
{route.name}
</button>
Expand Down
Loading

0 comments on commit 2e6c52a

Please sign in to comment.