Browse Source

refactor: redesign footer layout with grouped version info (#11758)

* refactor: redesign footer layout with grouped version info

Replace DefaultFooter with custom layout using createStyles.
Version info is now grouped by category (ver/hash, Umi, Utoo)
with label-value pairs in monospace font and pipe separators,
improving visual hierarchy and readability.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: add aria-hidden to footer separators and fix login test

- Add aria-hidden="true" to decorative pipe separators for screen readers
- Use regex match in login test to find "Ant Design Pro" text
  (now rendered as "Ant Design Pro © 2026" in the copyright line)
- Update test snapshots

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* refactor: replace custom pipe separators with antd Divider

Use Divider type="vertical" from antd instead of custom span pipes,
which gives proper semantic markup and consistent theme-aware styling.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
pull/11759/head
Alex Zhu 5 months ago
committed by GitHub
parent
commit
a6f6db6d10
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 160
      src/components/Footer/index.tsx
  2. 262
      src/pages/user/login/__snapshots__/login.test.tsx.snap
  3. 2
      src/pages/user/login/login.test.tsx

160
src/components/Footer/index.tsx

@ -1,6 +1,7 @@
import { GithubOutlined } from '@ant-design/icons';
import { DefaultFooter } from '@ant-design/pro-components';
import packageJson from '@root/package.json';
import { Divider } from 'antd';
import { createStyles } from 'antd-style';
import React from 'react';
const getRepoUrl = () => {
@ -10,66 +11,123 @@ const getRepoUrl = () => {
typeof packageJson.repository === 'string'
? packageJson.repository
: (packageJson.repository as { url: string }).url;
// Parse git URLs like git@github.com:owner/name.git or https://github.com/owner/name.git
const match = repo.match(/github\.com[:/]([^/]+)\/([^/.]+)/);
if (!match) return 'https://github.com/ant-design/ant-design-pro';
return `https://github.com/${match[1]}/${match[2]}`;
};
const REPO_URL = getRepoUrl();
// Git commit hash, resolved at build time from env vars or git
const COMMIT_HASH = process.env.COMMIT_HASH || '';
const useStyles = createStyles(({ token, css }) => ({
footer: css`
padding: 16px 24px;
text-align: center;
color: ${token.colorTextDescription};
font-size: ${token.fontSizeSM}px;
line-height: ${token.lineHeight};
background: transparent;
`,
copyright: css`
margin-bottom: 6px;
`,
link: css`
color: ${token.colorTextDescription};
text-decoration: none;
transition: color ${token.motionDurationMid};
&:hover {
color: ${token.colorText};
}
`,
meta: css`
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 6px 12px;
font-family: ${token.fontFamilyCode};
font-size: ${token.fontSizeSM - 1}px;
`,
group: css`
display: inline-flex;
align-items: center;
gap: 4px;
`,
label: css`
color: ${token.colorTextQuaternary};
`,
divider: css`
display: inline-block;
vertical-align: middle;
`,
}));
const Footer: React.FC = () => {
const { styles } = useStyles();
const year = new Date().getFullYear();
return (
<DefaultFooter
copyright={false}
style={{
background: 'none',
}}
links={[
{
key: 'version',
title: `v${__APP_VERSION__}`,
href: REPO_URL,
blankTarget: true,
},
{
key: 'umi',
title: `Umi ${__UMI_VERSION__}`,
href: 'https://umijs.org/',
blankTarget: true,
},
{
key: 'utoo',
title: `Utoo ${__UTOO_VERSION__}`,
href: 'https://utoo.land',
blankTarget: true,
},
...(COMMIT_HASH
? [
{
key: 'commit',
title: COMMIT_HASH.slice(0, 7),
href: `${REPO_URL}/commit/${COMMIT_HASH}`,
blankTarget: true,
},
]
: []),
{
key: 'repo',
title: (
<>
<GithubOutlined style={{ marginRight: 8 }} />
Ant Design Pro
</>
),
href: REPO_URL,
blankTarget: true,
},
]}
/>
<div className={styles.footer}>
<div className={styles.copyright}>Ant Design Pro &copy; {year}</div>
<div className={styles.meta}>
<span className={styles.group}>
<span className={styles.label}>ver</span>
<a
className={styles.link}
href={REPO_URL}
target="_blank"
rel="noopener noreferrer"
>
{__APP_VERSION__}
</a>
{COMMIT_HASH && (
<a
className={styles.link}
href={`${REPO_URL}/commit/${COMMIT_HASH}`}
target="_blank"
rel="noopener noreferrer"
>
{COMMIT_HASH.slice(0, 7)}
</a>
)}
</span>
<Divider type="vertical" className={styles.divider} />
<span className={styles.group}>
<span className={styles.label}>Umi</span>
<a
className={styles.link}
href="https://umijs.org/"
target="_blank"
rel="noopener noreferrer"
>
{__UMI_VERSION__}
</a>
</span>
<Divider type="vertical" className={styles.divider} />
<span className={styles.group}>
<span className={styles.label}>Utoo</span>
<a
className={styles.link}
href="https://utoo.land"
target="_blank"
rel="noopener noreferrer"
>
{__UTOO_VERSION__}
</a>
</span>
<Divider type="vertical" className={styles.divider} />
<a
className={styles.link}
href={REPO_URL}
target="_blank"
rel="noopener noreferrer"
>
<GithubOutlined style={{ marginRight: 4 }} />
GitHub
</a>
</div>
</div>
);
};

262
src/pages/user/login/__snapshots__/login.test.tsx.snap

@ -454,77 +454,110 @@ exports[`Login Page should login success 1`] = `
</div>
</div>
</div>
<footer
class="ant-layout-footer"
data-testid="pro-layout-footer"
style="padding: 0px; background: none;"
<div
class="acss-kiaa3f"
>
<div
class="ant-pro-global-footer"
data-testid="pro-global-footer"
class="acss-1iouf57"
>
<div
class="ant-pro-global-footer-list"
Ant Design Pro © 2026
</div>
<div
class="acss-1f94i0u"
>
<span
class="acss-84i4t5"
>
<span
class="acss-vpsqlh"
>
ver
</span>
<a
class="ant-pro-global-footer-list-link"
class="acss-1opaod3"
href="https://github.com/ant-design/ant-design-pro"
rel="noreferrer"
rel="noopener noreferrer"
target="_blank"
title="version"
>
vtest
test
</a>
</span>
<div
class="ant-divider css-var-_r_9_ ant-divider-vertical ant-divider-rail acss-10ntr2d"
role="separator"
/>
<span
class="acss-84i4t5"
>
<span
class="acss-vpsqlh"
>
Umi
</span>
<a
class="ant-pro-global-footer-list-link"
class="acss-1opaod3"
href="https://umijs.org/"
rel="noreferrer"
rel="noopener noreferrer"
target="_blank"
title="umi"
>
Umi 4.6.49
4.6.49
</a>
</span>
<div
class="ant-divider css-var-_r_9_ ant-divider-vertical ant-divider-rail acss-10ntr2d"
role="separator"
/>
<span
class="acss-84i4t5"
>
<span
class="acss-vpsqlh"
>
Utoo
</span>
<a
class="ant-pro-global-footer-list-link"
class="acss-1opaod3"
href="https://utoo.land"
rel="noreferrer"
rel="noopener noreferrer"
target="_blank"
title="utoo"
>
Utoo 1.4.2-alpha.0
1.4.2-alpha.0
</a>
<a
class="ant-pro-global-footer-list-link"
href="https://github.com/ant-design/ant-design-pro"
rel="noreferrer"
target="_blank"
title="repo"
</span>
<div
class="ant-divider css-var-_r_9_ ant-divider-vertical ant-divider-rail acss-10ntr2d"
role="separator"
/>
<a
class="acss-1opaod3"
href="https://github.com/ant-design/ant-design-pro"
rel="noopener noreferrer"
target="_blank"
>
<span
aria-label="github"
class="anticon anticon-github"
role="img"
style="margin-right: 4px;"
>
<span
aria-label="github"
class="anticon anticon-github"
role="img"
style="margin-right: 8px;"
<svg
aria-hidden="true"
data-icon="github"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="github"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0138.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"
/>
</svg>
</span>
Ant Design Pro
</a>
</div>
<path
d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0138.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"
/>
</svg>
</span>
GitHub
</a>
</div>
</footer>
</div>
</div>
</div>
</DocumentFragment>
@ -983,77 +1016,110 @@ exports[`Login Page should show login form 1`] = `
</div>
</div>
</div>
<footer
class="ant-layout-footer"
data-testid="pro-layout-footer"
style="padding: 0px; background: none;"
<div
class="acss-kiaa3f"
>
<div
class="ant-pro-global-footer"
data-testid="pro-global-footer"
class="acss-1iouf57"
>
<div
class="ant-pro-global-footer-list"
Ant Design Pro © 2026
</div>
<div
class="acss-1f94i0u"
>
<span
class="acss-84i4t5"
>
<span
class="acss-vpsqlh"
>
ver
</span>
<a
class="ant-pro-global-footer-list-link"
class="acss-1opaod3"
href="https://github.com/ant-design/ant-design-pro"
rel="noreferrer"
rel="noopener noreferrer"
target="_blank"
title="version"
>
vtest
test
</a>
</span>
<div
class="ant-divider css-var-_r_0_ ant-divider-vertical ant-divider-rail acss-10ntr2d"
role="separator"
/>
<span
class="acss-84i4t5"
>
<span
class="acss-vpsqlh"
>
Umi
</span>
<a
class="ant-pro-global-footer-list-link"
class="acss-1opaod3"
href="https://umijs.org/"
rel="noreferrer"
rel="noopener noreferrer"
target="_blank"
title="umi"
>
Umi 4.6.49
4.6.49
</a>
</span>
<div
class="ant-divider css-var-_r_0_ ant-divider-vertical ant-divider-rail acss-10ntr2d"
role="separator"
/>
<span
class="acss-84i4t5"
>
<span
class="acss-vpsqlh"
>
Utoo
</span>
<a
class="ant-pro-global-footer-list-link"
class="acss-1opaod3"
href="https://utoo.land"
rel="noreferrer"
rel="noopener noreferrer"
target="_blank"
title="utoo"
>
Utoo 1.4.2-alpha.0
1.4.2-alpha.0
</a>
<a
class="ant-pro-global-footer-list-link"
href="https://github.com/ant-design/ant-design-pro"
rel="noreferrer"
target="_blank"
title="repo"
</span>
<div
class="ant-divider css-var-_r_0_ ant-divider-vertical ant-divider-rail acss-10ntr2d"
role="separator"
/>
<a
class="acss-1opaod3"
href="https://github.com/ant-design/ant-design-pro"
rel="noopener noreferrer"
target="_blank"
>
<span
aria-label="github"
class="anticon anticon-github"
role="img"
style="margin-right: 4px;"
>
<span
aria-label="github"
class="anticon anticon-github"
role="img"
style="margin-right: 8px;"
<svg
aria-hidden="true"
data-icon="github"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
data-icon="github"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0138.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"
/>
</svg>
</span>
Ant Design Pro
</a>
</div>
<path
d="M511.6 76.3C264.3 76.2 64 276.4 64 523.5 64 718.9 189.3 885 363.8 946c23.5 5.9 19.9-10.8 19.9-22.2v-77.5c-135.7 15.9-141.2-73.9-150.3-88.9C215 726 171.5 718 184.5 703c30.9-15.9 62.4 4 98.9 57.9 26.4 39.1 77.9 32.5 104 26 5.7-23.5 17.9-44.5 34.7-60.8-140.6-25.2-199.2-111-199.2-213 0-49.5 16.3-95 48.3-131.7-20.4-60.5 1.9-112.3 4.9-120 58.1-5.2 118.5 41.6 123.2 45.3 33-8.9 70.7-13.6 112.9-13.6 42.4 0 80.2 4.9 113.5 13.9 11.3-8.6 67.3-48.8 121.3-43.9 2.9 7.7 24.7 58.3 5.5 118 32.4 36.8 48.9 82.7 48.9 132.3 0 102.2-59 188.1-200 212.9a127.5 127.5 0 0138.1 91v112.5c.8 9 0 17.9 15 17.9 177.1-59.7 304.6-227 304.6-424.1 0-247.2-200.4-447.3-447.5-447.3z"
/>
</svg>
</span>
GitHub
</a>
</div>
</footer>
</div>
</div>
</div>
</DocumentFragment>

2
src/pages/user/login/login.test.tsx

@ -81,7 +81,7 @@ describe('Login Page', () => {
await (await rootContainer.findByText('Login')).click();
// Wait for login to succeed and navigate to home page
await rootContainer.findByText('Ant Design Pro', undefined, {
await rootContainer.findByText(/Ant Design Pro/, undefined, {
timeout: 10000,
});

Loading…
Cancel
Save