fix: standardize direct page scroll viewports

This commit is contained in:
2026-07-28 22:50:11 +02:00
parent 324c26da78
commit 53e947935a
6 changed files with 67 additions and 32 deletions

View File

@@ -0,0 +1,23 @@
import type { HTMLAttributes, ReactNode } from "react";
export type PageScrollViewportProps = Omit<
HTMLAttributes<HTMLDivElement>,
"children"
> & {
children: ReactNode;
};
export default function PageScrollViewport({
children,
className = "",
...props
}: PageScrollViewportProps) {
return (
<div
{...props}
className={["page-scroll-viewport", className].filter(Boolean).join(" ")}
>
{children}
</div>
);
}

View File

@@ -6,6 +6,7 @@ import { dispatchPlatformViewChanged } from "../platform/views";
import { useGuardedNavigate } from "./UnsavedChangesGuard"; import { useGuardedNavigate } from "./UnsavedChangesGuard";
import Button from "./Button"; import Button from "./Button";
import Card from "./Card"; import Card from "./Card";
import PageScrollViewport from "./PageScrollViewport";
export default function ViewSurfaceRouteBoundary({ export default function ViewSurfaceRouteBoundary({
surfaceId, surfaceId,
@@ -33,6 +34,7 @@ export default function ViewSurfaceRouteBoundary({
} }
return ( return (
<PageScrollViewport>
<div className="content-pad"> <div className="content-pad">
<Card title="Outside the current view"> <Card title="Outside the current view">
<div className="empty-state"> <div className="empty-state">
@@ -54,5 +56,6 @@ export default function ViewSurfaceRouteBoundary({
</div> </div>
</Card> </Card>
</div> </div>
</PageScrollViewport>
); );
} }

View File

@@ -1,7 +1,9 @@
import Card from "../components/Card"; import Card from "../components/Card";
import PageScrollViewport from "../components/PageScrollViewport";
export default function PlaceholderPage({ title }: {title: string;}) { export default function PlaceholderPage({ title }: {title: string;}) {
return ( return (
<PageScrollViewport>
<div className="content-pad"> <div className="content-pad">
<div className="page-heading"> <div className="page-heading">
<h1>{title}</h1> <h1>{title}</h1>
@@ -10,6 +12,7 @@ export default function PlaceholderPage({ title }: {title: string;}) {
<Card> <Card>
<p className="muted">i18n:govoplan-core.next_passes_will_add_functionality_here.c13caade</p> <p className="muted">i18n:govoplan-core.next_passes_will_add_functionality_here.c13caade</p>
</Card> </Card>
</div>); </div>
</PageScrollViewport>);
} }

View File

@@ -1,5 +1,6 @@
import Card from "../../components/Card"; import Card from "../../components/Card";
import MetricCard from "../../components/MetricCard"; import MetricCard from "../../components/MetricCard";
import PageScrollViewport from "../../components/PageScrollViewport";
import PageTitle from "../../components/PageTitle"; import PageTitle from "../../components/PageTitle";
import { usePlatformModules } from "../../platform/ModuleContext"; import { usePlatformModules } from "../../platform/ModuleContext";
@@ -7,7 +8,8 @@ export default function DashboardPage() {
const modules = usePlatformModules(); const modules = usePlatformModules();
return ( return (
<div className="content-pad workspace-data-page core-dashboard-page"> <PageScrollViewport className="core-dashboard-page">
<div className="content-pad workspace-data-page">
<div className="page-heading split workspace-heading"> <div className="page-heading split workspace-heading">
<div> <div>
<PageTitle>i18n:govoplan-core.dashboard.d87f47b4</PageTitle> <PageTitle>i18n:govoplan-core.dashboard.d87f47b4</PageTitle>
@@ -37,7 +39,8 @@ export default function DashboardPage() {
<p className="muted">This minimal core home is only shown while no dashboard WebUI module is available. Feature modules own their pages and can expose dashboard widgets once the dashboard module is installed.</p> <p className="muted">This minimal core home is only shown while no dashboard WebUI module is available. Feature modules own their pages and can expose dashboard widgets once the dashboard module is installed.</p>
</Card> </Card>
</div> </div>
</div>); </div>
</PageScrollViewport>);
} }

View File

@@ -95,6 +95,8 @@ export { default as MetricCard } from "./components/MetricCard";
export { default as MessageDisplayPanel } from "./components/MessageDisplayPanel"; export { default as MessageDisplayPanel } from "./components/MessageDisplayPanel";
export type { MessageDisplayAttachment, MessageDisplayField } from "./components/MessageDisplayPanel"; export type { MessageDisplayAttachment, MessageDisplayField } from "./components/MessageDisplayPanel";
export { default as PageTitle } from "./components/PageTitle"; export { default as PageTitle } from "./components/PageTitle";
export { default as PageScrollViewport } from "./components/PageScrollViewport";
export type { PageScrollViewportProps } from "./components/PageScrollViewport";
export { default as PasswordField } from "./components/PasswordField"; export { default as PasswordField } from "./components/PasswordField";
export { default as PeoplePicker } from "./components/people/PeoplePicker"; export { default as PeoplePicker } from "./components/people/PeoplePicker";
export type { PeoplePickerProps } from "./components/people/PeoplePicker"; export type { PeoplePickerProps } from "./components/people/PeoplePicker";

View File

@@ -68,8 +68,10 @@
.section-link.active { border-left: 3px solid var(--accent); font-weight: 700; } .section-link.active { border-left: 3px solid var(--accent); font-weight: 700; }
.section-link.subtle { font-size: 13px; } .section-link.subtle { font-size: 13px; }
.workspace-content { min-width: 0; max-width: 100%; min-height: 0; overflow: auto; } .workspace-content { min-width: 0; max-width: 100%; min-height: 0; overflow: auto; }
.page-scroll-viewport { width: 100%; height: 100%; min-width: 0; min-height: 0; overflow: auto; }
.ui-no-sticky-section-sidebars .app-content { overflow: auto; } .ui-no-sticky-section-sidebars .app-content { overflow: auto; }
.ui-no-sticky-section-sidebars .workspace { height: auto; min-height: 100%; } .ui-no-sticky-section-sidebars .workspace { height: auto; min-height: 100%; }
.ui-no-sticky-section-sidebars .page-scroll-viewport { height: auto; min-height: 100%; overflow: visible; }
.ui-no-sticky-section-sidebars .section-sidebar { .ui-no-sticky-section-sidebars .section-sidebar {
height: max-content; height: max-content;
max-height: none; max-height: none;
@@ -83,7 +85,6 @@
.page-heading.split { display: flex; align-items: center; justify-content: space-between; } .page-heading.split { display: flex; align-items: center; justify-content: space-between; }
.module-entry-page { max-width: none; } .module-entry-page { max-width: none; }
.workspace-data-page .card { margin-bottom: 18px; } .workspace-data-page .card { margin-bottom: 18px; }
.core-dashboard-page { height: 100%; overflow: auto; }
.page-heading.workspace-heading { .page-heading.workspace-heading {
position: sticky; position: sticky;
top: 0; top: 0;