Skip to content

Commit

Permalink
Restructure the sidebar for better pointer handling (touch/mouse)
Browse files Browse the repository at this point in the history
Had to be restructured completely for reasonable outcome. Looks like I nailed it! Vertically and horizontally responsive. Cheers!
  • Loading branch information
mondoreale committed May 31, 2024
1 parent c38a5bb commit c179f11
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 180 deletions.
179 changes: 5 additions & 174 deletions src/components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { QueryClientProvider } from '@tanstack/react-query'
import 'mapbox-gl/dist/mapbox-gl.css'
import React, { HTMLAttributes, useEffect, useRef, useState } from 'react'
import React from 'react'
import { MapProvider } from 'react-map-gl'
import { BrowserRouter, Outlet, Route, Routes } from 'react-router-dom'
import { BrowserRouter, Route, Routes } from 'react-router-dom'
import styled, { css } from 'styled-components'
import { StoreProvider, useStore } from '../Store'
import { StoreProvider } from '../Store'
import {
useMap,
useSelectedNodeLocationEffect,
useSelectedPlaceLocationEffect,
useStreamIdParam,
} from '../hooks'
import { ActiveView } from '../types'
import { useAutoCenterNodeEffect, useHud } from '../utils'
import { useIsFetchingOperatorNodesForStream } from '../utils/nodes'
import { getQueryClient } from '../utils/queries'
Expand All @@ -24,7 +23,7 @@ import { MapNavigationControl } from './MapNavigationControl'
import NetworkSelector from './NetworkSelector'
import { NodeTopologyList } from './NodeTopologyList'
import { PublisherDetector } from './PublisherDetector'
import { SearchBox } from './SearchBox'
import { Sidebar } from './Sidebar'
import { StreamTopologyList } from './StreamTopologyList'
import StreamrClientProvider from './StreamrClientProvider'

Expand Down Expand Up @@ -55,18 +54,7 @@ function Page() {
<MapNavigationControl />
</Controls>
<Backdrop />
{(showSearch || showNodeList) && (
<SidebarContainer $compact={compact}>
<Sidebar>
{showSearch && <SearchBox />}
{showNodeList && (
<OutletWrap>
<Outlet />
</OutletWrap>
)}
</Sidebar>
</SidebarContainer>
)}
<Sidebar />
</ErrorBoundary>
</StoreProvider>
)
Expand All @@ -93,163 +81,6 @@ const NetworkSelectorWrap = styled.div<{ $alwaysGrow?: boolean }>`
}
`

const OutletWrap = styled.div`
display: none;
@media ${TabletMedia} {
display: block;
}
`

const SidebarContainer = styled.div<{ $compact?: boolean }>`
box-sizing: border-box;
height: 100vh;
left: 0;
overflow: hidden;
pointer-events: none;
position: absolute;
top: 0;
width: 100vw;
${({ $compact = false }) =>
$compact
? css`
padding-top: min(calc(40px + 20vw), 72px);
`
: css`
padding-top: min(calc(40px + 20vw), 104px);
`}
@media ${TabletMedia} {
overflow: auto;
padding-top: 0;
}
`

function Sidebar(props: HTMLAttributes<HTMLDivElement>) {
const { activeView, setActiveView } = useStore()

const sidebarRootRef = useRef<HTMLDivElement>(null)

useEffect(function handleInteractionsOutsideSidebar() {
function onMouseDown(e: MouseEvent) {
const { current: sidebarRoot } = sidebarRootRef

if (!sidebarRoot || !(e.target instanceof Element) || !sidebarRoot.contains(e.target)) {
setActiveView(ActiveView.Map)
}
}

window.addEventListener('mousedown', onMouseDown)

return () => {
window.removeEventListener('mousedown', onMouseDown)
}
}, [])

const [animate, setAnimate] = useState(true)

useEffect(function temporarilySuppressAnimationsOnResize() {
/**
* Disable animation during a resize to avoid lenghty transition
* between mobile sidebar (drawer) and desktop sidebar.
*/

let timeoutId: number | undefined

let mounted = true

function clearTimeout() {
if (timeoutId != null) {
window.clearTimeout(timeoutId)

timeoutId = undefined
}
}

function onWindowResize() {
setAnimate(false)

clearTimeout()

timeoutId = window.setTimeout(() => {
if (mounted) {
setAnimate(true)
}
}, 1000)
}

window.addEventListener('resize', onWindowResize)

return () => {
mounted = false

clearTimeout()

window.removeEventListener('resize', onWindowResize)
}
}, [])

const { compact } = useHud()

return (
<SidebarRoot
{...props}
ref={sidebarRootRef}
$animate={animate}
$expand={activeView === ActiveView.List}
$compact={compact}
/>
)
}

const SidebarRoot = styled.div<{ $expand?: boolean; $animate?: boolean; $compact?: boolean }>`
box-sizing: border-box;
max-height: 100%;
pointer-events: auto;
height: 100%;
${({ $animate = false }) =>
$animate &&
css`
transition: 0.3s ease-in-out transform;
`}
${({ $expand = false }) =>
!$expand &&
css`
transform: translateY(100%) translateY(-168px);
`}
&:empty {
display: none;
}
> * + * {
margin-top: 16px;
}
@media ${TabletMedia} {
box-sizing: content-box;
transform: translateY(0);
height: auto;
width: min(460px, max(360px, 50vw));
}
${({ $compact = false }) =>
$compact
? css`
@media ${TabletMedia} {
padding: 16px;
}
`
: css`
@media ${TabletMedia} {
padding: 32px;
}
`}
`

const Controls = styled.div<{ $compact?: boolean }>`
box-sizing: border-box;
display: flex;
Expand Down
8 changes: 6 additions & 2 deletions src/components/ControlBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ import { SANS } from '../utils/styled'

export const ControlBoxBorderRadius = 10

export const DefaultControlBoxBackgroundColor = '#fcfcfc'

export const ControlBoxShadow = '0 0 6px rgba(0, 0, 0, 0.08)'

const ControlBox = styled.div`
background: #fcfcfc;
box-shadow: 0 0 6px rgba(0, 0, 0, 0.08);
background: ${DefaultControlBoxBackgroundColor};
box-shadow: ${ControlBoxShadow};
border-radius: ${ControlBoxBorderRadius}px;
font-family: ${SANS};
`
Expand Down
2 changes: 2 additions & 0 deletions src/components/Graphs/Intervals.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,6 @@ export const Intervals = styled(UnstyledIntervals)`
justify-content: space-between;
align-content: center;
padding: 0 1rem;
min-width: 0;
overflow: hidden;
`
13 changes: 9 additions & 4 deletions src/components/NodeList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React, { ReactNode, RefObject } from 'react'
import styled from 'styled-components'
import { MEDIUM, SANS } from '../../utils/styled'
import ControlBox from '../ControlBox'
import Pager from './Pager'

export const NodeListInner = styled.div`
const NodeListInner = styled.div`
padding: 16px;
font-size: 12px;
Expand Down Expand Up @@ -38,8 +37,14 @@ interface NodeListProps {

export function NodeList({ innerRef, children }: NodeListProps) {
return (
<ControlBox ref={innerRef}>
<NodeListRoot ref={innerRef}>
<NodeListInner>{children}</NodeListInner>
</ControlBox>
</NodeListRoot>
)
}

const NodeListRoot = styled.div`
max-height: 100%;
overflow: auto;
pointer-events: auto;
`
6 changes: 6 additions & 0 deletions src/components/SearchBox/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,11 @@ export const Search = styled(ControlBox)`
grid-template-rows: auto 1fr;
height: 100%;
position: relative;
pointer-events: auto;
> * {
min-width: 0;
}
${Stats} {
background: #ffffff;
Expand Down Expand Up @@ -64,6 +69,7 @@ export const Search = styled(ControlBox)`
@media ${TabletMedia} {
border-radius: ${ControlBoxBorderRadius}px;
height: auto;
${Stats} {
border: 0;
Expand Down
Loading

0 comments on commit c179f11

Please sign in to comment.