Browse Source

fix: resolve jsx-a11y/anchor-is-valid and react-doctor lint warnings

Use semantic HTML approach for different link categories:

- **Action links** (with onClick/trigger actions): replace `<a href="#">`
  with `<Button type="link">` — semantically correct for non-navigation
  interactions (settings actions, edit/delete triggers, expand/collapse)
- **Navigation links** (user names, team members): replace `<a href="#">`
  with umi `<Link to="/" prefetch>` for proper client-side routing
- **Placeholder links** (demo data): replace `href="#"` with valid href
  using `item.href` from data or `/` as fallback
- **Wrapped button**: remove invalid `<a href="#">` wrapper around `<Button>`

Also fix react-doctor/no-prevent-default by removing preventDefault calls
from replaced anchor elements, and add eslint-disable comments for
react-doctor/rendering-hydration-mismatch-time false positives where
crypto.randomUUID() is only called in event handlers.

Closes #11784

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pull/11785/head
afc163 5 months ago
parent
commit
1a660e91c6
  1. 1
      README.md
  2. 1
      README.zh-CN.md
  3. 2
      docs/cheatsheet.en-US.md
  4. 2
      docs/cheatsheet.zh-CN.md
  5. 19
      src/components/TagSelect/index.tsx
  6. 2
      src/pages/account/center/components/Projects/index.tsx
  7. 14
      src/pages/account/settings/components/binding.tsx
  8. 22
      src/pages/account/settings/components/security.tsx
  9. 2
      src/pages/chatbot/index.tsx
  10. 8
      src/pages/dashboard/workplace/index.tsx
  11. 15
      src/pages/form/advanced-form/index.tsx
  12. 15
      src/pages/list/basic-list/index.tsx
  13. 16
      src/pages/list/card-list/index.tsx
  14. 17
      src/pages/list/search/articles/index.tsx
  15. 2
      src/pages/list/search/projects/index.tsx
  16. 6
      src/pages/profile/advanced/index.tsx
  17. 12
      src/pages/result/fail/index.tsx
  18. 4
      src/pages/result/success/index.tsx
  19. 13
      src/pages/table-list/index.tsx
  20. 48
      src/pages/user/login/__snapshots__/login.test.tsx.snap
  21. 2
      src/pages/user/login/index.tsx
  22. 8
      src/pages/user/register-result/index.tsx

1
README.md

@ -10,6 +10,7 @@ An out-of-box UI solution for enterprise applications as a React boilerplate.
[![Build With Umi](https://img.shields.io/badge/build%20with-umi-028fe4.svg)](https://umijs.org/) [![Build With Umi](https://img.shields.io/badge/build%20with-umi-028fe4.svg)](https://umijs.org/)
[![Checked with Biome](https://img.shields.io/badge/Checked_with-Biome-60a5fa?style=flat&logo=biome)](https://biomejs.dev) [![Checked with Biome](https://img.shields.io/badge/Checked_with-Biome-60a5fa?style=flat&logo=biome)](https://biomejs.dev)
[![Ant Design](https://badgen.net/badge/icon/Ant%20Design?icon=https://gw.alipayobjects.com/zos/antfincdn/Pp4WPgVDB3/KDpgvguMpGfqaHPjicRK.svg&label)](https://ant.design/) [![Ant Design](https://badgen.net/badge/icon/Ant%20Design?icon=https://gw.alipayobjects.com/zos/antfincdn/Pp4WPgVDB3/KDpgvguMpGfqaHPjicRK.svg&label)](https://ant.design/)
[![React Review](https://react.review/api/badge/ant-design/ant-design-pro)](https://react.review/repo/ant-design/ant-design-pro)
Language: 🇺🇸 | [🇨🇳](./README.zh-CN.md) Language: 🇺🇸 | [🇨🇳](./README.zh-CN.md)

1
README.zh-CN.md

@ -12,6 +12,7 @@ Language : [🇺🇸](./README.md) | 🇨🇳
[![Build With Umi](https://img.shields.io/badge/build%20with-umi-028fe4.svg)](https://umijs.org/) [![Build With Umi](https://img.shields.io/badge/build%20with-umi-028fe4.svg)](https://umijs.org/)
[![Checked with Biome](https://img.shields.io/badge/Checked_with-Biome-60a5fa?style=flat&logo=biome)](https://biomejs.dev) [![Checked with Biome](https://img.shields.io/badge/Checked_with-Biome-60a5fa?style=flat&logo=biome)](https://biomejs.dev)
[![Ant Design](https://badgen.net/badge/icon/Ant%20Design?icon=https://gw.alipayobjects.com/zos/antfincdn/Pp4WPgVDB3/KDpgvguMpGfqaHPjicRK.svg&label)](https://ant.design/) [![Ant Design](https://badgen.net/badge/icon/Ant%20Design?icon=https://gw.alipayobjects.com/zos/antfincdn/Pp4WPgVDB3/KDpgvguMpGfqaHPjicRK.svg&label)](https://ant.design/)
[![React Review](https://react.review/api/badge/ant-design/ant-design-pro)](https://react.review/repo/ant-design/ant-design-pro)
![](https://github.com/user-attachments/assets/fde29061-3d9a-4397-8ac2-397b0e033ef5) ![](https://github.com/user-attachments/assets/fde29061-3d9a-4397-8ac2-397b0e033ef5)

2
docs/cheatsheet.en-US.md

@ -1,6 +1,6 @@
# Ant Design Pro Cheatsheet # Ant Design Pro Cheatsheet
[![GitHub](https://img.shields.io/badge/GitHub-ant--design%2Fant--design--pro-181717?logo=github)](https://github.com/ant-design/ant-design-pro) [![Stars](https://img.shields.io/github/stars/ant-design/ant-design-pro?style=social)](https://github.com/ant-design/ant-design-pro) [![Version](https://img.shields.io/github/package-json/v/ant-design/ant-design-pro)](https://github.com/ant-design/ant-design-pro/releases) [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![GitHub](https://img.shields.io/badge/GitHub-ant--design%2Fant--design--pro-181717?logo=github)](https://github.com/ant-design/ant-design-pro) [![Stars](https://img.shields.io/github/stars/ant-design/ant-design-pro?style=social)](https://github.com/ant-design/ant-design-pro) [![Version](https://img.shields.io/github/package-json/v/ant-design/ant-design-pro)](https://github.com/ant-design/ant-design-pro/releases) [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![React Review](https://react.review/api/badge/ant-design/ant-design-pro)](https://react.review/repo/ant-design/ant-design-pro)
![Ant Design Pro](https://mdn.alipayobjects.com/huamei_fkc4p0/afts/img/A*EX3ISYC2ghEAAAAAddAAAAgAeobDAQ/original) ![Ant Design Pro](https://mdn.alipayobjects.com/huamei_fkc4p0/afts/img/A*EX3ISYC2ghEAAAAAddAAAAgAeobDAQ/original)

2
docs/cheatsheet.zh-CN.md

@ -1,6 +1,6 @@
# Ant Design Pro Cheatsheet # Ant Design Pro Cheatsheet
[![GitHub](https://img.shields.io/badge/GitHub-ant--design%2Fant--design--pro-181717?logo=github)](https://github.com/ant-design/ant-design-pro) [![Stars](https://img.shields.io/github/stars/ant-design/ant-design-pro?style=social)](https://github.com/ant-design/ant-design-pro) [![Version](https://img.shields.io/github/package-json/v/ant-design/ant-design-pro)](https://github.com/ant-design/ant-design-pro/releases) [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![GitHub](https://img.shields.io/badge/GitHub-ant--design%2Fant--design--pro-181717?logo=github)](https://github.com/ant-design/ant-design-pro) [![Stars](https://img.shields.io/github/stars/ant-design/ant-design-pro?style=social)](https://github.com/ant-design/ant-design-pro) [![Version](https://img.shields.io/github/package-json/v/ant-design/ant-design-pro)](https://github.com/ant-design/ant-design-pro/releases) [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-339933?logo=node.js&logoColor=white)](https://nodejs.org/) [![React Review](https://react.review/api/badge/ant-design/ant-design-pro)](https://react.review/repo/ant-design/ant-design-pro)
![Ant Design Pro](https://mdn.alipayobjects.com/huamei_fkc4p0/afts/img/A*EX3ISYC2ghEAAAAAddAAAAgAeobDAQ/original) ![Ant Design Pro](https://mdn.alipayobjects.com/huamei_fkc4p0/afts/img/A*EX3ISYC2ghEAAAAAddAAAAgAeobDAQ/original)

19
src/components/TagSelect/index.tsx

@ -1,6 +1,6 @@
import { DownOutlined, UpOutlined } from '@ant-design/icons'; import { DownOutlined, UpOutlined } from '@ant-design/icons';
import { useMergedState } from '@rc-component/util'; import { useMergedState } from '@rc-component/util';
import { Tag } from 'antd'; import { Button, Tag } from 'antd';
import { clsx } from 'clsx'; import { clsx } from 'clsx';
import React, { type FC, useMemo, useState } from 'react'; import React, { type FC, useMemo, useState } from 'react';
import useStyles from './index.style'; import useStyles from './index.style';
@ -136,19 +136,10 @@ const TagSelect: FC<TagSelectProps> & {
return child; return child;
})} })}
{expandable && ( {expandable && (
<a <Button
type="link"
className={styles.trigger} className={styles.trigger}
href="#" onClick={() => setExpand(!expand)}
onClick={(e) => {
e.preventDefault();
setExpand(!expand);
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
setExpand(!expand);
}
}}
> >
{expand ? ( {expand ? (
<> <>
@ -160,7 +151,7 @@ const TagSelect: FC<TagSelectProps> & {
<DownOutlined /> <DownOutlined />
</> </>
)} )}
</a> </Button>
)} )}
</div> </div>
); );

2
src/pages/account/center/components/Projects/index.tsx

@ -36,7 +36,7 @@ const Projects: React.FC = () => {
cover={<img alt={item.title} src={item.cover} />} cover={<img alt={item.title} src={item.cover} />}
> >
<Card.Meta <Card.Meta
title={<a href="#">{item.title}</a>} title={<a href={item.href}>{item.title}</a>}
description={item.subDescription} description={item.subDescription}
/> />
<div className={styles.cardItemContent}> <div className={styles.cardItemContent}>

14
src/pages/account/settings/components/binding.tsx

@ -3,7 +3,7 @@ import {
DingdingOutlined, DingdingOutlined,
TaobaoOutlined, TaobaoOutlined,
} from '@ant-design/icons'; } from '@ant-design/icons';
import { List } from 'antd'; import { Button, List } from 'antd';
import React from 'react'; import React from 'react';
const BindingView: React.FC = () => { const BindingView: React.FC = () => {
@ -12,9 +12,9 @@ const BindingView: React.FC = () => {
title: '绑定淘宝', title: '绑定淘宝',
description: '当前未绑定淘宝账号', description: '当前未绑定淘宝账号',
actions: [ actions: [
<a key="Bind" href="#"> <Button key="Bind" type="link">
绑定 绑定
</a>, </Button>,
], ],
avatar: <TaobaoOutlined className="taobao" />, avatar: <TaobaoOutlined className="taobao" />,
}, },
@ -22,9 +22,9 @@ const BindingView: React.FC = () => {
title: '绑定支付宝', title: '绑定支付宝',
description: '当前未绑定支付宝账号', description: '当前未绑定支付宝账号',
actions: [ actions: [
<a key="Bind" href="#"> <Button key="Bind" type="link">
绑定 绑定
</a>, </Button>,
], ],
avatar: <AlipayOutlined className="alipay" />, avatar: <AlipayOutlined className="alipay" />,
}, },
@ -32,9 +32,9 @@ const BindingView: React.FC = () => {
title: '绑定钉钉', title: '绑定钉钉',
description: '当前未绑定钉钉账号', description: '当前未绑定钉钉账号',
actions: [ actions: [
<a key="Bind" href="#"> <Button key="Bind" type="link">
绑定 绑定
</a>, </Button>,
], ],
avatar: <DingdingOutlined className="dingding" />, avatar: <DingdingOutlined className="dingding" />,
}, },

22
src/pages/account/settings/components/security.tsx

@ -1,4 +1,4 @@
import { List } from 'antd'; import { Button, List } from 'antd';
import React from 'react'; import React from 'react';
type Unpacked<T> = T extends (infer U)[] ? U : T; type Unpacked<T> = T extends (infer U)[] ? U : T;
@ -20,45 +20,45 @@ const SecurityView: React.FC = () => {
</> </>
), ),
actions: [ actions: [
<a key="Modify" href="#"> <Button key="Modify" type="link">
修改 修改
</a>, </Button>,
], ],
}, },
{ {
title: '密保手机', title: '密保手机',
description: `已绑定手机:138****8293`, description: `已绑定手机:138****8293`,
actions: [ actions: [
<a key="Modify" href="#"> <Button key="Modify" type="link">
修改 修改
</a>, </Button>,
], ],
}, },
{ {
title: '密保问题', title: '密保问题',
description: '未设置密保问题,密保问题可有效保护账户安全', description: '未设置密保问题,密保问题可有效保护账户安全',
actions: [ actions: [
<a key="Set" href="#"> <Button key="Set" type="link">
设置 设置
</a>, </Button>,
], ],
}, },
{ {
title: '备用邮箱', title: '备用邮箱',
description: `已绑定邮箱:ant***sign.com`, description: `已绑定邮箱:ant***sign.com`,
actions: [ actions: [
<a key="Modify" href="#"> <Button key="Modify" type="link">
修改 修改
</a>, </Button>,
], ],
}, },
{ {
title: 'MFA 设备', title: 'MFA 设备',
description: '未绑定 MFA 设备,绑定后,可以进行二次确认', description: '未绑定 MFA 设备,绑定后,可以进行二次确认',
actions: [ actions: [
<a key="bind" href="#"> <Button key="bind" type="link">
绑定 绑定
</a>, </Button>,
], ],
}, },
]; ];

2
src/pages/chatbot/index.tsx

@ -180,6 +180,7 @@ const ChatbotPage: React.FC = () => {
}; };
const newChat = () => { const newChat = () => {
// eslint-disable-next-line react-doctor/rendering-hydration-mismatch-time -- only called in event handlers, not during render
const key = crypto.randomUUID(); const key = crypto.randomUUID();
setConversations((prev) => [ setConversations((prev) => [
{ key, label: '新对话', group: '今天', isDraft: true }, { key, label: '新对话', group: '今天', isDraft: true },
@ -261,6 +262,7 @@ const ChatbotPage: React.FC = () => {
(c) => c.key !== conversation.key, (c) => c.key !== conversation.key,
); );
if (next.length === 0) { if (next.length === 0) {
// eslint-disable-next-line react-doctor/rendering-hydration-mismatch-time -- only called in event handlers, not during render
const key = crypto.randomUUID(); const key = crypto.randomUUID();
next.push({ next.push({
key, key,

8
src/pages/dashboard/workplace/index.tsx

@ -118,9 +118,9 @@ const Workplace: FC = () => {
avatar={<Avatar src={item.user.avatar} />} avatar={<Avatar src={item.user.avatar} />}
title={ title={
<span> <span>
<a className={styles.username} href="#"> <Link className={styles.username} to="/" prefetch>
{item.user.name} {item.user.name}
</a> </Link>
&nbsp; &nbsp;
<span className={styles.event}>{events}</span> <span className={styles.event}>{events}</span>
</span> </span>
@ -281,12 +281,12 @@ const Workplace: FC = () => {
{projectNotice.map((item) => { {projectNotice.map((item) => {
return ( return (
<Col span={12} key={`members-item-${item.id}`}> <Col span={12} key={`members-item-${item.id}`}>
<a href="#"> <Link to="/" prefetch>
<Avatar src={item.logo} size="small" /> <Avatar src={item.logo} size="small" />
<span className={styles.member}> <span className={styles.member}>
{item.member.substring(0, 3)} {item.member.substring(0, 3)}
</span> </span>
</a> </Link>
</Col> </Col>
); );
})} })}

15
src/pages/form/advanced-form/index.tsx

@ -10,7 +10,7 @@ import {
ProFormText, ProFormText,
ProFormTimePicker, ProFormTimePicker,
} from '@ant-design/pro-components'; } from '@ant-design/pro-components';
import { Card, Col, message, Popover, Row } from 'antd'; import { Button, Card, Col, message, Popover, Row } from 'antd';
import type { FC } from 'react'; import type { FC } from 'react';
import { useRef, useState } from 'react'; import { useRef, useState } from 'react';
import { fakeSubmitForm } from './service'; import { fakeSubmitForm } from './service';
@ -161,16 +161,13 @@ const AdvancedForm: FC<Record<string, any>> = () => {
valueType: 'option', valueType: 'option',
render: (_, record: TableFormDateType, _index, action) => { render: (_, record: TableFormDateType, _index, action) => {
return [ return [
<a <Button
key="eidit" key="edit"
href="#" type="link"
onClick={(e) => { onClick={() => action?.startEditable(record.key)}
e.preventDefault();
action?.startEditable(record.key);
}}
> >
编辑 编辑
</a>, </Button>,
]; ];
}, },
}, },

15
src/pages/list/basic-list/index.tsx

@ -171,9 +171,9 @@ const BasicList: FC = () => {
], ],
}} }}
> >
<a href="#"> <Button type="link">
更多 <DownOutlined /> 更多 <DownOutlined />
</a> </Button>
</Dropdown> </Dropdown>
); );
}; };
@ -229,16 +229,13 @@ const BasicList: FC = () => {
renderItem={(item) => ( renderItem={(item) => (
<List.Item <List.Item
actions={[ actions={[
<a <Button
key="edit" key="edit"
href="#" type="link"
onClick={(e) => { onClick={() => showEditModal(item)}
e.preventDefault();
showEditModal(item);
}}
> >
编辑 编辑
</a>, </Button>,
renderMoreBtn(item), renderMoreBtn(item),
]} ]}
> >

16
src/pages/list/card-list/index.tsx

@ -22,21 +22,21 @@ const CardList = () => {
提供跨越设计与开发的体验解决方案。 提供跨越设计与开发的体验解决方案。
</p> </p>
<div className={styles.contentLink}> <div className={styles.contentLink}>
<a href="#"> <a href="/">
<img <img
alt="" alt=""
src="https://gw.alipayobjects.com/zos/rmsportal/MjEImQtenlyueSmVEfUD.svg" src="https://gw.alipayobjects.com/zos/rmsportal/MjEImQtenlyueSmVEfUD.svg"
/>{' '} />{' '}
快速开始 快速开始
</a> </a>
<a href="#"> <a href="/">
<img <img
alt="" alt=""
src="https://gw.alipayobjects.com/zos/rmsportal/NbuDUAuBlIApFuDvWiND.svg" src="https://gw.alipayobjects.com/zos/rmsportal/NbuDUAuBlIApFuDvWiND.svg"
/>{' '} />{' '}
产品简介 产品简介
</a> </a>
<a href="#"> <a href="/">
<img <img
alt="" alt=""
src="https://gw.alipayobjects.com/zos/rmsportal/ohOEPSYdDTNnyMbGuyLb.svg" src="https://gw.alipayobjects.com/zos/rmsportal/ohOEPSYdDTNnyMbGuyLb.svg"
@ -79,12 +79,12 @@ const CardList = () => {
hoverable hoverable
className={styles.card} className={styles.card}
actions={[ actions={[
<a key="option1" href="#"> <Button type="link" key="option1">
操作一 操作一
</a>, </Button>,
<a key="option2" href="#"> <Button type="link" key="option2">
操作二 操作二
</a>, </Button>,
]} ]}
> >
<Card.Meta <Card.Meta
@ -95,7 +95,7 @@ const CardList = () => {
src={item.avatar} src={item.avatar}
/> />
} }
title={<a href="#">{item.title}</a>} title={<a href={item.href}>{item.title}</a>}
description={ description={
<Paragraph <Paragraph
className={styles.item} className={styles.item}

17
src/pages/list/search/articles/index.tsx

@ -183,22 +183,13 @@ const Articles: FC = () => {
options={ownerOptions} options={ownerOptions}
/> />
</FormItem> </FormItem>
<a <Button
type="link"
className={styles.selfTrigger} className={styles.selfTrigger}
href="#" onClick={() => setOwner()}
onClick={(e) => {
e.preventDefault();
setOwner();
}}
onKeyDown={(e) => {
if (e.key === 'Enter') {
e.preventDefault();
setOwner();
}
}}
> >
只看自己的 只看自己的
</a> </Button>
</StandardFormRow> </StandardFormRow>
<StandardFormRow title="其它选项" grid last> <StandardFormRow title="其它选项" grid last>
<Row gutter={16}> <Row gutter={16}>

2
src/pages/list/search/projects/index.tsx

@ -50,7 +50,7 @@ const Projects: FC = () => {
cover={<img alt={item.title} src={item.cover} />} cover={<img alt={item.title} src={item.cover} />}
> >
<Card.Meta <Card.Meta
title={<a href="#">{item.title}</a>} title={<a href={item.href}>{item.title}</a>}
description={ description={
<Paragraph <Paragraph
ellipsis={{ ellipsis={{

6
src/pages/profile/advanced/index.tsx

@ -150,7 +150,7 @@ const descriptionItems: DescriptionsProps['items'] = [
{ key: '1', label: '创建人', children: '曲丽丽' }, { key: '1', label: '创建人', children: '曲丽丽' },
{ key: '2', label: '订购产品', children: 'XX 服务' }, { key: '2', label: '订购产品', children: 'XX 服务' },
{ key: '3', label: '创建时间', children: '2017-07-07' }, { key: '3', label: '创建时间', children: '2017-07-07' },
{ key: '4', label: '关联单据', children: <a href="#">12421</a> }, { key: '4', label: '关联单据', children: <a href="/">12421</a> },
{ key: '5', label: '生效日期', children: '2017-07-07 ~ 2017-08-08' }, { key: '5', label: '生效日期', children: '2017-07-07 ~ 2017-08-08' },
{ key: '6', label: '备注', children: '请于两个工作日内确认' }, { key: '6', label: '备注', children: '请于两个工作日内确认' },
]; ];
@ -305,7 +305,9 @@ const Advanced: FC = () => {
}} }}
/> />
<div> <div>
<a href="#">催一下</a> <Button type="link" size="small">
催一下
</Button>
</div> </div>
</div> </div>
); );

12
src/pages/result/fail/index.tsx

@ -22,15 +22,15 @@ export default () => {
className={styles.error_icon} className={styles.error_icon}
/> />
<span>您的账户已被冻结</span> <span>您的账户已被冻结</span>
<a <Button
href="#" type="link"
style={{ style={{
marginLeft: 16, marginLeft: 16,
}} }}
> >
<span>立即解冻</span> <span>立即解冻</span>
<RightOutlined /> <RightOutlined />
</a> </Button>
</div> </div>
<div> <div>
<CloseCircleOutlined <CloseCircleOutlined
@ -40,15 +40,15 @@ export default () => {
className={styles.error_icon} className={styles.error_icon}
/> />
<span>您的账户还不具备申请资格</span> <span>您的账户还不具备申请资格</span>
<a <Button
href="#" type="link"
style={{ style={{
marginLeft: 16, marginLeft: 16,
}} }}
> >
<span>立即升级</span> <span>立即升级</span>
<RightOutlined /> <RightOutlined />
</a> </Button>
</div> </div>
</> </>
); );

4
src/pages/result/success/index.tsx

@ -51,7 +51,7 @@ const Success: React.FC = () => {
}} }}
> >
<span>周毛毛</span> <span>周毛毛</span>
<a href="#"> <Button type="link">
<DingdingOutlined <DingdingOutlined
style={{ style={{
color: '#00A0E9', color: '#00A0E9',
@ -59,7 +59,7 @@ const Success: React.FC = () => {
}} }}
/> />
<span>催一下</span> <span>催一下</span>
</a> </Button>
</div> </div>
</div> </div>
); );

13
src/pages/table-list/index.tsx

@ -58,16 +58,15 @@ const TableList: React.FC = () => {
dataIndex: 'name', dataIndex: 'name',
render: (dom, entity) => { render: (dom, entity) => {
return ( return (
<a <Button
href="#" type="link"
onClick={(e) => { onClick={() => {
e.preventDefault();
setCurrentRow(entity); setCurrentRow(entity);
setShowDetail(true); setShowDetail(true);
}} }}
> >
{dom} {dom}
</a> </Button>
); );
}, },
}, },
@ -197,12 +196,12 @@ const TableList: React.FC = () => {
render: (_, record) => [ render: (_, record) => [
<UpdateForm <UpdateForm
trigger={ trigger={
<a href="#"> <Button type="link">
<FormattedMessage <FormattedMessage
id="pages.searchTable.config" id="pages.searchTable.config"
defaultMessage="Configuration" defaultMessage="Configuration"
/> />
</a> </Button>
} }
key="config" key="config"
onOk={actionRef.current?.reload} onOk={actionRef.current?.reload}

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

@ -884,27 +884,35 @@ exports[`Login Page should show login form 1`] = `
class="ant-input-suffix" class="ant-input-suffix"
> >
<span <span
aria-label="eye-invisible" aria-disabled="false"
class="anticon anticon-eye-invisible ant-input-password-icon" aria-label="Show"
role="img" aria-pressed="false"
tabindex="-1" class="ant-input-password-icon"
role="button"
tabindex="0"
> >
<svg <span
aria-hidden="true" aria-label="eye-invisible"
data-icon="eye-invisible" class="anticon anticon-eye-invisible"
fill="currentColor" role="img"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
> >
<path <svg
d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z" aria-hidden="true"
/> data-icon="eye-invisible"
<path fill="currentColor"
d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z" focusable="false"
/> height="1em"
</svg> viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"
/>
<path
d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"
/>
</svg>
</span>
</span> </span>
</span> </span>
</span> </span>
@ -948,7 +956,7 @@ exports[`Login Page should show login form 1`] = `
type="button" type="button"
> >
<span> <span>
Login 登 录
</span> </span>
</button> </button>
</form> </form>

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

@ -398,7 +398,7 @@ const Login: React.FC = () => {
/> />
</ProFormCheckbox> </ProFormCheckbox>
<a <a
href="#" href="/"
style={{ style={{
float: 'right', float: 'right',
}} }}

8
src/pages/user/register-result/index.tsx

@ -9,11 +9,9 @@ const RegisterResult: React.FC<Record<string, unknown>> = () => {
const actions = ( const actions = (
<div className={styles.actions}> <div className={styles.actions}>
<a href="#"> <Button size="large" type="primary">
<Button size="large" type="primary"> <span>查看邮箱</span>
<span>查看邮箱</span> </Button>
</Button>
</a>
<Link to="/" prefetch> <Link to="/" prefetch>
<Button size="large">返回首页</Button> <Button size="large">返回首页</Button>
</Link> </Link>

Loading…
Cancel
Save