Files
app/frontend/src/components/Dashboard/PanelRail.tsx
T
stroblme 2c605b2c13 Float the dashboard rail along the bottom on a phone
Below md a dashboard stacks to one column and dropped its rail. The rail is
now a horizontal row in the dashboard's own look, floated over the bottom
of the screen on /panel/{id} and above the dock in the app's view, with
44px items, sideways scrolling when it overflows, and padding so the last
tile clears it; a panel's read-only notice moves up out of its way. The
three looks share the geometry from ui/core.
2026-10-06 00:22:28 +02:00

49 lines
1.6 KiB
TypeScript

import { useQueries } from "@tanstack/react-query"
import type { LinkProps } from "@tanstack/react-router"
import { dashboardQueryOptions } from "@/components/Dashboard/queries"
import { useUi } from "./ui"
/**
* Switching between the dashboards one panel was assigned.
*
* Permanent rather than a menu behind a button: a wall panel is glanced at,
* and something you have to open first is something nobody opens. It costs
* about a fortieth of the canvas, which `CanvasSurface` absorbs by scaling —
* the grid itself never changes, so an arrangement made without the rail still
* fits with it.
*
* Drawn in the dashboard's own look, because it hangs on the same screen: a
* rail wearing the app's chrome beside a glass panel is two designs at once.
* On a phone it is a row the caller floats along the bottom.
*
* Reading the dashboards it links to is also what fills the labels, and it
* warms the cache for the neighbours so a switch draws immediately.
*/
export function PanelRail({
dashboards,
current,
linkFor,
horizontal,
}: {
dashboards: string[]
current: string
linkFor: (name: string) => LinkProps
horizontal?: boolean
}) {
const { Rail } = useUi()
const entries = useQueries({
queries: dashboards.map((name) => dashboardQueryOptions(name)),
combine: (results) =>
results.map((result, index) => ({
name: dashboards[index],
label: result.data?.title || dashboards[index],
icon: result.data?.icon ?? "",
active: dashboards[index] === current,
link: linkFor(dashboards[index]),
})),
})
return <Rail entries={entries} horizontal={horizontal} />
}