From cfdec922a9227788b95ff103e6303321a18ae2d2 Mon Sep 17 00:00:00 2001 From: Eddie Maldonado Date: Tue, 28 Nov 2023 09:45:29 -0500 Subject: [PATCH 01/12] refactor: put old breakpoints in map rather than separate constants --- assets/css/_ladder_page.scss | 4 ++-- assets/css/_map_page.scss | 4 ++-- assets/css/_notification_drawer.scss | 4 ++-- assets/css/_picker_container.scss | 2 +- assets/css/_properties_panel.scss | 4 ++-- assets/css/_search_page.scss | 2 +- assets/css/_swings_view.scss | 4 ++-- assets/css/_ui_kit.scss | 2 +- assets/css/app.scss | 7 ++++--- 9 files changed, 17 insertions(+), 16 deletions(-) diff --git a/assets/css/_ladder_page.scss b/assets/css/_ladder_page.scss index 756076fac..b94856a38 100644 --- a/assets/css/_ladder_page.scss +++ b/assets/css/_ladder_page.scss @@ -17,13 +17,13 @@ $color-route-tabs-separator: #9fa2ac; padding-left: $route-picker-width; } -@media screen and (max-width: $mobile-max-width) { +@media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { .c-ladder-page--picker-container-visible { padding-left: $mobile-route-picker-width; } } -@media screen and (max-width: $mobile-max-width) { +@media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { .c-ladder-page--picker-container-visible { .c-ladder-page__tab-bar-and-ladders { @include blur; diff --git a/assets/css/_map_page.scss b/assets/css/_map_page.scss index 1f0e72826..76c832e9b 100644 --- a/assets/css/_map_page.scss +++ b/assets/css/_map_page.scss @@ -22,7 +22,7 @@ $z-map-page-context: ( z-index: map-get($z-map-page-context, "map"); .c-map-page__input-and-results--visible ~ & { - @media screen and (max-width: $mobile-portrait-max-width) { + @media screen and (max-width: map-get($old-breakpoints, "mobile-portrait-max-width")) { filter: blur(3.25px); } } @@ -102,7 +102,7 @@ $z-map-page-context: ( display: none; .c-map-page__input-and-results--visible ~ & { - @media screen and (max-width: $mobile-portrait-max-width) { + @media screen and (max-width: map-get($old-breakpoints, "mobile-portrait-max-width")) { // Make button clickable display: block; // Force Flex + Posistion to fill area diff --git a/assets/css/_notification_drawer.scss b/assets/css/_notification_drawer.scss index cf513e729..20727753d 100644 --- a/assets/css/_notification_drawer.scss +++ b/assets/css/_notification_drawer.scss @@ -10,10 +10,10 @@ width: 23.5rem; z-index: map-get($z-page-layout-context, "view"); - @media screen and (max-width: $mobile-max-width) { + @media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { width: 100%; } - @media screen and (max-width: $mobile-portrait-max-width) { + @media screen and (max-width: map-get($old-breakpoints, "mobile-portrait-max-width")) { position: fixed; bottom: 0; } diff --git a/assets/css/_picker_container.scss b/assets/css/_picker_container.scss index d447a0aee..e52fb8ec9 100644 --- a/assets/css/_picker_container.scss +++ b/assets/css/_picker_container.scss @@ -35,7 +35,7 @@ display: none; } -@media screen and (max-width: $mobile-max-width) { +@media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { .c-picker-container { --picker-container-width: min( #{$mobile-route-picker-width}, diff --git a/assets/css/_properties_panel.scss b/assets/css/_properties_panel.scss index 83a134c05..c956226fa 100644 --- a/assets/css/_properties_panel.scss +++ b/assets/css/_properties_panel.scss @@ -11,14 +11,14 @@ width: 23.5rem; z-index: map-get($z-page-layout-context, "properties-panel"); - @media screen and (max-width: $mobile-max-width) { + @media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { width: 100vw; .l-nav__app-content & { width: 100%; } } - @media screen and (max-width: $mobile-portrait-max-width) { + @media screen and (max-width: map-get($old-breakpoints, "mobile-portrait-max-width")) { position: fixed; bottom: 0; } diff --git a/assets/css/_search_page.scss b/assets/css/_search_page.scss index d86fef322..c9d23fe5c 100644 --- a/assets/css/_search_page.scss +++ b/assets/css/_search_page.scss @@ -61,7 +61,7 @@ $z-search-page-context: ( padding: 0.625rem 1rem 0 1rem; } -@media screen and (max-width: $mobile-max-width) { +@media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { .c-search-page { flex-direction: column; } diff --git a/assets/css/_swings_view.scss b/assets/css/_swings_view.scss index 26142b6b2..8c81fa8a2 100644 --- a/assets/css/_swings_view.scss +++ b/assets/css/_swings_view.scss @@ -27,7 +27,7 @@ } } } - @media screen and (max-width: $mobile-portrait-max-width) { + @media screen and (max-width: map-get($old-breakpoints, "mobile-portrait-max-width")) { position: fixed; bottom: 0; width: 100vw; @@ -215,7 +215,7 @@ } } -@media screen and (max-width: $mobile-max-width) { +@media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { .c-swings-view__header { padding-left: 1.75rem; } diff --git a/assets/css/_ui_kit.scss b/assets/css/_ui_kit.scss index 7e32eb1b2..84479f354 100644 --- a/assets/css/_ui_kit.scss +++ b/assets/css/_ui_kit.scss @@ -441,7 +441,7 @@ $font-family-route-pill: "Helvetica Neue", Helvetica, Arial, sans-serif; filter: blur(5px); } -@media screen and (max-width: $mobile-max-width) { +@media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { .blurred-mobile { @include blur; } diff --git a/assets/css/app.scss b/assets/css/app.scss index 7ce00e550..59fe82c88 100644 --- a/assets/css/app.scss +++ b/assets/css/app.scss @@ -1,6 +1,7 @@ -$non-mobile-min-width: 768px; -$mobile-max-width: $non-mobile-min-width - 1; -$mobile-portrait-max-width: 480px; +$old-breakpoints: ( + "mobile-max-width": 767px, + "mobile-portrait-max-width": 480px, +); $tab-bar-width: 3rem; $drawer-tab-width: 2rem; $route-picker-width: 21.875rem; From 1da97b9aa61cad6d78ec3618bd81264df80b9afd Mon Sep 17 00:00:00 2001 From: Eddie Maldonado Date: Tue, 28 Nov 2023 13:08:03 -0500 Subject: [PATCH 02/12] feat: initial change for properties panel --- assets/css/_properties_panel.scss | 8 ++------ assets/css/_skate_ui.scss | 6 ++++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/assets/css/_properties_panel.scss b/assets/css/_properties_panel.scss index c956226fa..4808e7450 100644 --- a/assets/css/_properties_panel.scss +++ b/assets/css/_properties_panel.scss @@ -11,14 +11,10 @@ width: 23.5rem; z-index: map-get($z-page-layout-context, "properties-panel"); - @media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { + @media screen and (max-width: map-get($breakpoints, "max-mobile-landscape-tablet-portrait-width")) { width: 100vw; - - .l-nav__app-content & { - width: 100%; - } } - @media screen and (max-width: map-get($old-breakpoints, "mobile-portrait-max-width")) { + @media screen and (max-width: map-get($breakpoints, "max-mobile-width")) { position: fixed; bottom: 0; } diff --git a/assets/css/_skate_ui.scss b/assets/css/_skate_ui.scss index 71ef4a0e7..2f389d1fa 100644 --- a/assets/css/_skate_ui.scss +++ b/assets/css/_skate_ui.scss @@ -1,3 +1,9 @@ +$breakpoints: ( + "max-mobile-width": 480px, + "max-mobile-landscape-tablet-portrait-width": 800px, + "max-tablet-width": 1340px, +); + // #region Text Styles [v2] // https://www.notion.so/mbta-downtown-crossing/2022-12-19-Type-Styles-6f6c90eb449248b7a954e234b718137f From 83044f340244d18c0f2b12f67d61268a0a49dd35 Mon Sep 17 00:00:00 2001 From: Eddie Maldonado Date: Tue, 28 Nov 2023 13:27:57 -0500 Subject: [PATCH 03/12] feat: hide nav when view is open below 800px breakpoint --- assets/src/components/nav.tsx | 17 ++++- .../src/components/nav/mobilePortraitNav.tsx | 16 +++-- assets/tests/components/nav.test.tsx | 51 +++++++++++++++ .../components/nav/mobilePortraitNav.test.tsx | 63 ++----------------- 4 files changed, 77 insertions(+), 70 deletions(-) diff --git a/assets/src/components/nav.tsx b/assets/src/components/nav.tsx index 428d9910c..1bd3a9231 100644 --- a/assets/src/components/nav.tsx +++ b/assets/src/components/nav.tsx @@ -6,6 +6,8 @@ import LeftNav from "./nav/leftNav" import TopNav from "./nav/topNav" import MobilePortraitNav from "./nav/mobilePortraitNav" import { StateDispatchContext } from "../contexts/stateDispatchContext" +import { usePanelStateFromStateDispatchContext } from "../hooks/usePanelState" +import { OpenView } from "../state/pagePanelState" interface Props { children?: React.ReactNode @@ -15,19 +17,30 @@ const Nav: React.FC = ({ children }) => { const [, dispatch] = useContext(StateDispatchContext) const deviceType = useScreenSize() + const { + currentView: { openView, selectedVehicleOrGhost }, + } = usePanelStateFromStateDispatchContext() + const isViewOpen = + openView !== OpenView.None || (selectedVehicleOrGhost && true) || false + + const navVisibilityStyle = isViewOpen ? "hidden" : "visible" + switch (deviceType) { case "mobile": return (
{children}
- +
) case "mobile_landscape_tablet_portrait": return (
{children}
-
+
dispatch(toggleMobileMenu())} defaultToCollapsed={true} diff --git a/assets/src/components/nav/mobilePortraitNav.tsx b/assets/src/components/nav/mobilePortraitNav.tsx index decfb6336..f59cd6e6b 100644 --- a/assets/src/components/nav/mobilePortraitNav.tsx +++ b/assets/src/components/nav/mobilePortraitNav.tsx @@ -3,20 +3,18 @@ import { StateDispatchContext } from "../../contexts/stateDispatchContext" import { toggleMobileMenu } from "../../state" import BottomNavMobile from "./bottomNavMobile" import TopNavMobile from "./topNavMobile" -import { OpenView } from "../../state/pagePanelState" import { usePanelStateFromStateDispatchContext } from "../../hooks/usePanelState" -const MobilePortraitNav = (): JSX.Element => { +const MobilePortraitNav = ({ + isViewOpen, +}: { + isViewOpen: boolean +}): JSX.Element => { const [state, dispatch] = useContext(StateDispatchContext) const { mobileMenuIsOpen, routeTabs } = state - const { - currentView: { openView, selectedVehicleOrGhost }, - openNotificationDrawer, - openSwingsView, - } = usePanelStateFromStateDispatchContext() - - const isViewOpen = openView !== OpenView.None || selectedVehicleOrGhost + const { openNotificationDrawer, openSwingsView } = + usePanelStateFromStateDispatchContext() const navVisibilityStyle = isViewOpen ? "hidden" : "visible" diff --git a/assets/tests/components/nav.test.tsx b/assets/tests/components/nav.test.tsx index 88d236260..08b15b465 100644 --- a/assets/tests/components/nav.test.tsx +++ b/assets/tests/components/nav.test.tsx @@ -8,6 +8,11 @@ import Nav from "../../src/components/nav" import useScreenSize from "../../src/hooks/useScreenSize" import getTestGroups from "../../src/userTestGroups" import { TestGroups } from "../../src/userInTestGroup" +import { StateDispatchProvider } from "../../src/contexts/stateDispatchContext" +import stateFactory from "../factories/applicationState" +import { viewFactory } from "../factories/pagePanelStateFactory" +import { OpenView } from "../../src/state/pagePanelState" +import vehicleFactory from "../factories/vehicle" jest.mock("../../src/hooks/useScreenSize", () => ({ __esModule: true, @@ -52,6 +57,52 @@ describe("Nav", () => { expect(result.queryByText("Route Ladders")).toBeNull() }) + test("renders mobile landscape / tablet portrait nav content with nav elements hidden when a view is open", () => { + jest + .mocked(useScreenSize) + .mockReturnValueOnce("mobile_landscape_tablet_portrait") + const dispatch = jest.fn() + + const result = render( + + + + + + ) + + expect(result.getByTitle("Route Ladders")).not.toBeVisible() + }) + + test("renders mobile landscape / tablet portrait nav content with nav elements hidden when a vehicle is selected", () => { + jest + .mocked(useScreenSize) + .mockReturnValueOnce("mobile_landscape_tablet_portrait") + const dispatch = jest.fn() + + const result = render( + + + + + + ) + + expect(result.getByTitle("Route Ladders")).not.toBeVisible() + }) + test("renders tablet nav content", () => { ;(useScreenSize as jest.Mock).mockImplementationOnce(() => "tablet") diff --git a/assets/tests/components/nav/mobilePortraitNav.test.tsx b/assets/tests/components/nav/mobilePortraitNav.test.tsx index 0be787836..00da35801 100644 --- a/assets/tests/components/nav/mobilePortraitNav.test.tsx +++ b/assets/tests/components/nav/mobilePortraitNav.test.tsx @@ -7,10 +7,6 @@ import MobilePortraitNav from "../../../src/components/nav/mobilePortraitNav" import { StateDispatchProvider } from "../../../src/contexts/stateDispatchContext" import { initialState } from "../../../src/state" import { BrowserRouter } from "react-router-dom" -import vehicleFactory from "../../factories/vehicle" -import stateFactory from "../../factories/applicationState" -import { OpenView } from "../../../src/state/pagePanelState" -import { viewFactory } from "../../factories/pagePanelStateFactory" describe("MobilePortraitNav", () => { test("renders top / bottom nav", () => { @@ -18,7 +14,7 @@ describe("MobilePortraitNav", () => { const result = render( - + ) @@ -27,63 +23,12 @@ describe("MobilePortraitNav", () => { expect(result.queryByTitle("Notifications")).toBeVisible() }) - test("doesn't render top / bottom nav when a view is open", () => { + test("doesn't render top / bottom nav when a view or panel is open", () => { const dispatch = jest.fn() const result = render( - - - - - - ) - - expect(result.queryByTitle("Swings View")).not.toBeVisible() - expect(result.queryByTitle("Notifications")).not.toBeVisible() - }) - - test("doesn't render top / bottom nav when a vehicle is selected", () => { - const dispatch = jest.fn() - const result = render( - - - - - - ) - - expect(result.queryByTitle("Swings View")).not.toBeVisible() - expect(result.queryByTitle("Notifications")).not.toBeVisible() - }) - - test("doesn't render top / bottom nav when notification drawer is open", () => { - const dispatch = jest.fn() - const result = render( - + - + ) From f1d8f18c5849368e6dd6ce504b9a50935d82183e Mon Sep 17 00:00:00 2001 From: Eddie Maldonado Date: Tue, 28 Nov 2023 13:32:56 -0500 Subject: [PATCH 04/12] feat: swings view full width below 800px --- assets/css/_swings_view.scss | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/assets/css/_swings_view.scss b/assets/css/_swings_view.scss index 8c81fa8a2..3ce666ef5 100644 --- a/assets/css/_swings_view.scss +++ b/assets/css/_swings_view.scss @@ -18,19 +18,18 @@ } // Full width on mobile portrait, to be updated with more responsive designs - @media screen and (max-width: 480px) { + @media screen and (max-width: map-get($breakpoints, "max-mobile-landscape-tablet-portrait-width")) { .l-nav__app-content & { - width: 100%; + width: 100vw; .c-swings-view__table { width: 100%; } } } - @media screen and (max-width: map-get($old-breakpoints, "mobile-portrait-max-width")) { + @media screen and (max-width: map-get($breakpoints, "max-mobile-width")) { position: fixed; bottom: 0; - width: 100vw; } } From b5b581958613a5f6d507df6725320cb205b9d3e9 Mon Sep 17 00:00:00 2001 From: Eddie Maldonado Date: Tue, 28 Nov 2023 13:34:53 -0500 Subject: [PATCH 05/12] feat: notifications drawer full width below 800px --- assets/css/_notification_drawer.scss | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/css/_notification_drawer.scss b/assets/css/_notification_drawer.scss index 20727753d..e8c5ff7a3 100644 --- a/assets/css/_notification_drawer.scss +++ b/assets/css/_notification_drawer.scss @@ -10,10 +10,10 @@ width: 23.5rem; z-index: map-get($z-page-layout-context, "view"); - @media screen and (max-width: map-get($old-breakpoints, "mobile-max-width")) { - width: 100%; + @media screen and (max-width: map-get($breakpoints, "max-mobile-landscape-tablet-portrait-width")) { + width: 100vw; } - @media screen and (max-width: map-get($old-breakpoints, "mobile-portrait-max-width")) { + @media screen and (max-width: map-get($breakpoints, "max-mobile-width")) { position: fixed; bottom: 0; } From a7d5dbde2996b82a83875462a40778a53140fea2 Mon Sep 17 00:00:00 2001 From: Eddie Maldonado Date: Tue, 28 Nov 2023 13:48:24 -0500 Subject: [PATCH 06/12] feat: show back buttons below 800px --- assets/src/components/viewHeader.tsx | 5 +- assets/tests/components/viewHeader.test.tsx | 66 +++++++++++++++------ 2 files changed, 51 insertions(+), 20 deletions(-) diff --git a/assets/src/components/viewHeader.tsx b/assets/src/components/viewHeader.tsx index 762f3df70..b40614ed9 100644 --- a/assets/src/components/viewHeader.tsx +++ b/assets/src/components/viewHeader.tsx @@ -31,11 +31,14 @@ const ViewHeader: ViewHeaderType = ({ }): JSX.Element => { const deviceType = useScreenSize() + const screenSizeAllowsBackButton = + deviceType === "mobile" || deviceType === "mobile_landscape_tablet_portrait" + return (
{backlinkToView && backlinkToView !== OpenView.None && - deviceType === "mobile" ? ( + screenSizeAllowsBackButton ? (