Skip to content

Commit 62c9657

Browse files
authored
Hosting Dashboard v2: view transitions (part 1) (#103278)
1 parent d9b4f12 commit 62c9657

File tree

28 files changed

+324
-171
lines changed

28 files changed

+324
-171
lines changed

client/dashboard/agency-overview/index.tsx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,23 @@ import PageLayout from '../components/page-layout';
55

66
export default function AgencyOverview() {
77
return (
8-
<PageLayout>
9-
<PageHeader
10-
title={ __( 'Agency Overview' ) }
11-
actions={
12-
<>
13-
<Button variant="primary" __next40pxDefaultSize>
14-
{ __( 'Add Sites' ) }
15-
</Button>
16-
<Button variant="secondary" __next40pxDefaultSize>
17-
{ __( 'Add Products' ) }
18-
</Button>
19-
</>
20-
}
21-
description={ __( 'This is a sample overview page.' ) }
22-
/>
23-
</PageLayout>
8+
<PageLayout
9+
header={
10+
<PageHeader
11+
title={ __( 'Agency Overview' ) }
12+
actions={
13+
<>
14+
<Button variant="primary" __next40pxDefaultSize>
15+
{ __( 'Add Sites' ) }
16+
</Button>
17+
<Button variant="secondary" __next40pxDefaultSize>
18+
{ __( 'Add Products' ) }
19+
</Button>
20+
</>
21+
}
22+
description={ __( 'This is a sample overview page.' ) }
23+
/>
24+
}
25+
></PageLayout>
2426
);
2527
}

client/dashboard/app/404/index.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,19 @@ import RouterLinkButton from '../../components/router-link-button';
55

66
function NotFound() {
77
return (
8-
<PageLayout>
9-
<PageHeader
10-
title={ __( '404 Not Found' ) }
11-
description={ __( 'The page you are looking for does not exist.' ) }
12-
actions={
13-
<RouterLinkButton to="/sites" variant="primary" __next40pxDefaultSize>
14-
{ __( 'Go to Sites' ) }
15-
</RouterLinkButton>
16-
}
17-
/>
18-
</PageLayout>
8+
<PageLayout
9+
header={
10+
<PageHeader
11+
title={ __( '404 Not Found' ) }
12+
description={ __( 'The page you are looking for does not exist.' ) }
13+
actions={
14+
<RouterLinkButton to="/sites" variant="primary" __next40pxDefaultSize>
15+
{ __( 'Go to Sites' ) }
16+
</RouterLinkButton>
17+
}
18+
/>
19+
}
20+
/>
1921
);
2022
}
2123

client/dashboard/app/500/index.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,24 @@ import RouterLinkButton from '../../components/router-link-button';
66

77
function UnknownError( { error }: { error: Error } ) {
88
return (
9-
<PageLayout>
10-
<PageHeader
11-
title={ __( '500 Error' ) }
12-
description={ __( 'Something wrong happened.' ) }
13-
actions={
14-
<RouterLinkButton to="/sites" variant="primary" __next40pxDefaultSize>
15-
{ __( 'Go to Sites' ) }
16-
</RouterLinkButton>
17-
}
18-
/>
19-
<Notice status="error" isDismissible={ false }>
20-
{ error.message }
21-
</Notice>
22-
</PageLayout>
9+
<PageLayout
10+
header={
11+
<PageHeader
12+
title={ __( '500 Error' ) }
13+
description={ __( 'Something wrong happened.' ) }
14+
actions={
15+
<RouterLinkButton to="/sites" variant="primary" __next40pxDefaultSize>
16+
{ __( 'Go to Sites' ) }
17+
</RouterLinkButton>
18+
}
19+
/>
20+
}
21+
notices={
22+
<Notice status="error" isDismissible={ false }>
23+
{ error.message }
24+
</Notice>
25+
}
26+
></PageLayout>
2327
);
2428
}
2529

client/dashboard/app/router.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,11 @@ export const getRouter = ( config: AppConfig ) => {
348348
defaultNotFoundComponent: NotFound,
349349
defaultPreload: 'intent',
350350
defaultPreloadStaleTime: 0,
351+
// Calling document.startViewTransition() ourselves is really tricky,
352+
// Tanstack Router knows how to do it best. Even though it says
353+
// "default", we can still customize it in CSS and add more transition
354+
// areas.
355+
defaultViewTransition: true,
351356
} );
352357
};
353358

client/dashboard/app/secondary-menu/index.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ function UserProfile() {
5757
<Text variant="muted">@{ user.username }</Text>
5858
</VStack>
5959
<MenuGroup>
60-
<RouterLinkMenuItem to="/me/profile">{ __( 'Account' ) }</RouterLinkMenuItem>
60+
<RouterLinkMenuItem to="/me/profile" onClick={ onClose }>
61+
{ __( 'Account' ) }
62+
</RouterLinkMenuItem>
6163
</MenuGroup>
6264
<MenuGroup>
6365
<MenuItem

client/dashboard/app/style.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
// I'm tempted to even just replace all this with a display:none on the logo
66
@import './loading-screen';
77

8+
@import './view-transitions';
9+
810
// Hacks that shouldn't be necessary.
911
.environment-badge {
1012
display: none;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
::view-transition-old(root),
2+
::view-transition-new(root) {
3+
animation-duration: 250ms;
4+
}
5+
6+
// The main and sub headers must be separate view transitions, othervise the sub
7+
// header won't slide in!
8+
header.dashboard-header-bar {
9+
view-transition-name: main-header;
10+
}
11+
main div.dashboard-header-bar {
12+
view-transition-name: sub-header;
13+
}
14+
15+
// Headers should show on top of the rest of the page (important for sticky).
16+
::view-transition-group(main-header),
17+
::view-transition-group(sub-header) {
18+
z-index: 1;
19+
}
20+
21+
// Do not let the browser transform (slide in) the main hear. This is important
22+
// for sticy positioning (when the page is scrolled down) and gently switching
23+
// between the main and sub headers.
24+
::view-transition-group(main-header) {
25+
transform: none !important;
26+
}
27+
28+
::view-transition-image-pair(main-header),
29+
::view-transition-image-pair(sub-header) {
30+
height: auto;
31+
}
32+
33+
// Large and small must be separate so they don't cross-animate.
34+
.dashboard-page-layout.is-large .client-dashboard-components-page-header {
35+
view-transition-name: page-layout-header-large;
36+
}
37+
.dashboard-page-layout.is-small .client-dashboard-components-page-header {
38+
view-transition-name: page-layout-header-small;
39+
}
40+
41+
.dashboard-page-layout.is-large .client-dashboard-components-page-header .components-button.is-primary {
42+
view-transition-name: page-layout-header-large--button;
43+
}
44+
45+
::view-transition-old(page-layout-header-large--button),
46+
::view-transition-new(page-layout-header-large--button) {
47+
height: 100%;
48+
}
49+
50+
.dashboard-page-layout__content {
51+
view-transition-name: page-layout-content;
52+
}
53+
54+
::view-transition-old(page-layout-content),
55+
::view-transition-new(page-layout-content) {
56+
// Never expand the main content horizontally, but allow it to shrink.
57+
width: auto;
58+
// Also disable shrinking. Leaving it commented out to test.
59+
// max-width: 100%;
60+
height: auto;
61+
}
62+
63+
::view-transition-image-pair(page-layout-content) {
64+
display: flex;
65+
justify-content: center;
66+
}

client/dashboard/components/page-header/index.tsx

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const PageHeader = ( {
3939
breadcrumbs,
4040
}: PageHeaderProps ) => {
4141
return (
42-
<VStack spacing={ 2 }>
42+
<VStack spacing={ 2 } className="client-dashboard-components-page-header">
4343
{ breadcrumbs }
4444
<HStack spacing={ 4 } justify="flex-start" alignment="flex-start">
4545
{ decoration && (
@@ -49,16 +49,15 @@ export const PageHeader = ( {
4949
) }
5050
<HStack spacing={ 3 } justify="space-between" alignment="flex-start">
5151
<h1 className="client-dashboard-components-page-header__heading">{ title }</h1>
52-
{ !! actions && (
53-
<HStack
54-
spacing={ 2 }
55-
justify="flex-end"
56-
expanded={ false }
57-
className="client-dashboard-components-page-header__actions"
58-
>
59-
{ actions }
60-
</HStack>
61-
) }
52+
{ /* The wrapper is always needed for view transitions. */ }
53+
<HStack
54+
spacing={ 2 }
55+
justify="flex-end"
56+
expanded={ false }
57+
className="client-dashboard-components-page-header__actions"
58+
>
59+
{ actions }
60+
</HStack>
6261
</HStack>
6362
</HStack>
6463
{ description && (

client/dashboard/components/page-header/style.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
.client-dashboard-components-page-header__actions {
3434
flex-shrink: 0;
35+
align-self: stretch;
3536
}
3637

3738
.client-dashboard-components-page-header__description {

client/dashboard/components/page-layout/index.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,26 @@ const sizes = {
88

99
function PageLayout( {
1010
children,
11+
header,
12+
notices,
1113
size = 'large',
1214
}: {
1315
children?: React.ReactNode;
16+
header?: React.ReactNode;
17+
notices?: React.ReactNode;
1418
size?: 'large' | 'small';
1519
} ) {
1620
return (
17-
<VStack spacing={ 8 } className="dashboard-page-layout" style={ sizes[ size ] }>
18-
{ children }
21+
<VStack
22+
spacing={ 8 }
23+
className={ `dashboard-page-layout is-${ size }` }
24+
style={ sizes[ size ] }
25+
>
26+
{ header }
27+
{ notices }
28+
<VStack spacing={ 8 } className="dashboard-page-layout__content">
29+
{ children }
30+
</VStack>
1931
</VStack>
2032
);
2133
}

client/dashboard/domains/index.tsx

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -100,15 +100,18 @@ function Domains() {
100100
}
101101
const { data: filteredData, paginationInfo } = filterSortAndPaginate( domains, view, fields );
102102
return (
103-
<PageLayout>
104-
<PageHeader
105-
title={ __( 'Domains' ) }
106-
actions={
107-
<Button variant="primary" __next40pxDefaultSize>
108-
{ __( 'Add New Domain' ) }
109-
</Button>
110-
}
111-
/>
103+
<PageLayout
104+
header={
105+
<PageHeader
106+
title={ __( 'Domains' ) }
107+
actions={
108+
<Button variant="primary" __next40pxDefaultSize>
109+
{ __( 'Add New Domain' ) }
110+
</Button>
111+
}
112+
/>
113+
}
114+
>
112115
<DataViewsCard>
113116
<DataViews
114117
data={ filteredData || [] }

client/dashboard/emails/index.tsx

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -118,23 +118,28 @@ function Emails() {
118118
};
119119

120120
return (
121-
<PageLayout>
122-
<PageHeader
123-
title={ __( 'Emails' ) }
124-
actions={
125-
<>
126-
<Button variant="secondary" __next40pxDefaultSize>
127-
{ __( 'Add Email Forwarder' ) }
128-
</Button>
129-
<Button variant="primary" __next40pxDefaultSize>
130-
{ __( 'Add Mailbox' ) }
131-
</Button>
132-
</>
133-
}
134-
/>
135-
<Notice status="warning" isDismissible={ false }>
136-
{ __( 'This is using fake data for the moment' ) }
137-
</Notice>
121+
<PageLayout
122+
header={
123+
<PageHeader
124+
title={ __( 'Emails' ) }
125+
actions={
126+
<>
127+
<Button variant="secondary" __next40pxDefaultSize>
128+
{ __( 'Add Email Forwarder' ) }
129+
</Button>
130+
<Button variant="primary" __next40pxDefaultSize>
131+
{ __( 'Add Mailbox' ) }
132+
</Button>
133+
</>
134+
}
135+
/>
136+
}
137+
notices={
138+
<Notice status="warning" isDismissible={ false }>
139+
{ __( 'This is using fake data for the moment' ) }
140+
</Notice>
141+
}
142+
>
138143
<DataViewsCard>
139144
<DataViews
140145
data={ filteredData }

client/dashboard/me/active-subscriptions/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import PageLayout from '../../components/page-layout';
44

55
export default function ActiveSubscriptions() {
66
return (
7-
<PageLayout size="small">
8-
<PageHeader title={ __( 'Active Subscriptions' ) } />
7+
<PageLayout size="small" header={ <PageHeader title={ __( 'Active Subscriptions' ) } /> }>
98
<div>Active subscriptions content will go here</div>
109
</PageLayout>
1110
);

client/dashboard/me/billing-history/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import PageLayout from '../../components/page-layout';
44

55
function BillingHistory() {
66
return (
7-
<PageLayout size="small">
8-
<PageHeader title={ __( 'Billing History' ) } />
7+
<PageLayout size="small" header={ <PageHeader title={ __( 'Billing History' ) } /> }>
98
<div>Billing history content will go here</div>
109
</PageLayout>
1110
);

client/dashboard/me/billing/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ import RouterLinkSummaryButton from '../../components/router-link-summary-button
1313

1414
function Billing() {
1515
return (
16-
<PageLayout size="small">
17-
<PageHeader title={ __( 'Billing' ) } />
16+
<PageLayout size="small" header={ <PageHeader title={ __( 'Billing' ) } /> }>
1817
<VStack spacing={ 4 }>
1918
<RouterLinkSummaryButton
2019
title={ __( 'Active subscriptions' ) }

0 commit comments

Comments
 (0)