chore: merge master

This commit is contained in:
afc163 2025-01-17 11:39:45 +08:00
commit 8d935acb80
34 changed files with 763 additions and 299 deletions

View File

@ -20,6 +20,7 @@ interface ChangelogInfo {
version: string; version: string;
changelog: string; changelog: string;
refs: string[]; refs: string[];
contributors: string[];
releaseDate: string; releaseDate: string;
} }
@ -160,14 +161,30 @@ const ParseChangelog: React.FC<{ changelog: string }> = (props) => {
return <span>{parsedChangelog}</span>; return <span>{parsedChangelog}</span>;
}; };
const RefLinks: React.FC<{ refs: string[] }> = ({ refs }) => { const RefLinks: React.FC<{ refs: string[]; contributors: string[] }> = ({ refs, contributors }) => {
const { styles } = useStyle(); const { styles } = useStyle();
return ( return (
<> <>
{refs?.map((ref) => ( {refs?.map((ref) => (
<a className={styles.linkRef} key={ref} href={ref} target="_blank" rel="noreferrer"> <React.Fragment key={ref}>
#{ref.match(/[^/]+$/)?.[0]} <a className={styles.linkRef} key={ref} href={ref} target="_blank" rel="noreferrer">
</a> #{ref.match(/[^/]+$/)?.[0]}
</a>
</React.Fragment>
))}
{contributors?.map((contributor) => (
<React.Fragment key={contributor}>
<a
className={styles.linkRef}
key={contributor}
href={`https://github.com/${contributor}`}
target="_blank"
rel="noreferrer"
>
@{contributor}
</a>
</React.Fragment>
))} ))}
</> </>
); );
@ -178,7 +195,7 @@ const RenderChangelogList: React.FC<{ changelogList: ChangelogInfo[] }> = ({ cha
const { styles } = useStyle(); const { styles } = useStyle();
const len = changelogList.length; const len = changelogList.length;
for (let i = 0; i < len; i += 1) { for (let i = 0; i < len; i += 1) {
const { refs, changelog } = changelogList[i]; const { refs, changelog, contributors } = changelogList[i];
// Check if the next line is an image link and append it to the current line // Check if the next line is an image link and append it to the current line
if (i + 1 < len && changelogList[i + 1].changelog.trim().startsWith('<img')) { if (i + 1 < len && changelogList[i + 1].changelog.trim().startsWith('<img')) {
const imgDom = new DOMParser().parseFromString(changelogList[i + 1].changelog, 'text/html'); const imgDom = new DOMParser().parseFromString(changelogList[i + 1].changelog, 'text/html');
@ -186,7 +203,7 @@ const RenderChangelogList: React.FC<{ changelogList: ChangelogInfo[] }> = ({ cha
elements.push( elements.push(
<li key={i}> <li key={i}>
<ParseChangelog changelog={changelog} /> <ParseChangelog changelog={changelog} />
<RefLinks refs={refs} /> <RefLinks refs={refs} contributors={contributors} />
<br /> <br />
<img <img
src={imgElement?.getAttribute('src') || ''} src={imgElement?.getAttribute('src') || ''}
@ -200,7 +217,7 @@ const RenderChangelogList: React.FC<{ changelogList: ChangelogInfo[] }> = ({ cha
elements.push( elements.push(
<li key={i}> <li key={i}>
<ParseChangelog changelog={changelog} /> <ParseChangelog changelog={changelog} />
<RefLinks refs={refs} /> <RefLinks refs={refs} contributors={contributors} />
</li>, </li>,
); );
} }

View File

@ -5,7 +5,7 @@ on:
- cron: "0 0 * * *" # Run at 00:00 every day - cron: "0 0 * * *" # Run at 00:00 every day
permissions: permissions:
issues: write # Need write permission to modify issue assignees issues: write
jobs: jobs:
reminder_job: reminder_job:
@ -15,16 +15,18 @@ jobs:
uses: actions/github-script@v7 uses: actions/github-script@v7
with: with:
script: | script: |
const daysBeforeReminder = 14; const daysBeforeReminder = 14;
let page = 1; let page = 1;
const perPage = 100; const perPage = 100;
const reminderSignature = "This issue has been inactive for more than 14 days";
while (true) { while (true) {
const { data: issues } = await github.rest.issues.listForRepo({ const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
state: 'open', state: 'open',
assignee: '*', // Filter assigned issues assignee: '*',
per_page: perPage, per_page: perPage,
page: page, page: page,
}); });
@ -53,16 +55,30 @@ jobs:
); );
if (daysInactive >= daysBeforeReminder && !hasLinkedPR) { if (daysInactive >= daysBeforeReminder && !hasLinkedPR) {
const assigneesMentions = issue.assignees // get issue comments
.map(user => `@${user.login}`) const { data: comments } = await github.rest.issues.listComments({
.join(' ');
await github.rest.issues.createComment({
owner: context.repo.owner, owner: context.repo.owner,
repo: context.repo.repo, repo: context.repo.repo,
issue_number: issue.number, issue_number: issue.number,
body: `${assigneesMentions} 这个 issue 已经超过 14 天没有更新或关联 PR。如果您仍在处理这个 issue请更新进度如果您无法继续处理请联系维护者重新分配。\n\nThis issue has been inactive for more than 14 days without any updates or linked PR. If you are still working on this issue, please provide a progress update. If you are unable to continue, please contact the maintainers for reassignment.`,
}); });
// check if reminder has been sent
const hasReminder = comments.some(comment =>
comment.body.includes(reminderSignature)
);
if (!hasReminder) {
const assigneesMentions = issue.assignees
.map(user => `@${user.login}`)
.join(' ');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: `${assigneesMentions} 这个 issue 已经超过 14 天没有更新或关联 PR。如果您仍在处理这个 issue请更新进度如果您无法继续处理请联系维护者重新分配。\n\nThis issue has been inactive for more than 14 days without any updates or linked PR. If you are still working on this issue, please provide a progress update. If you are unable to continue, please contact the maintainers for reassignment.`,
});
}
} }
} }

View File

@ -102,6 +102,20 @@ describe('Descriptions', () => {
expect(container.querySelectorAll('.ant-descriptions-item')[6]).toHaveAttribute('colSpan', '2'); expect(container.querySelectorAll('.ant-descriptions-item')[6]).toHaveAttribute('colSpan', '2');
}); });
it('when column=6, last item span should be 5', () => {
const { container } = render(
<Descriptions
column={6}
items={[
{ label: '0', children: '' },
{ label: '1', children: '', span: 2 },
]}
/>,
);
expect(container.querySelectorAll('.ant-descriptions-item')[0]).toHaveAttribute('colSpan', '1');
expect(container.querySelectorAll('.ant-descriptions-item')[1]).toHaveAttribute('colSpan', '5');
});
it('column is number', () => { it('column is number', () => {
const wrapper = render( const wrapper = render(
<Descriptions column={3}> <Descriptions column={3}>

View File

@ -53,7 +53,7 @@ function getCalcRows(
if (count < mergedColumn) { if (count < mergedColumn) {
// If the span of the last element in the current row is less than the column, then add its span to the remaining columns // If the span of the last element in the current row is less than the column, then add its span to the remaining columns
const last = rows[rows.length - 1]; const last = rows[rows.length - 1];
last.span = mergedColumn - count + 1; last.span = mergedColumn - (count - (last.span || 1));
return rows; return rows;
} }
return rows; return rows;

View File

@ -421,6 +421,7 @@ const genAllowClearStyle = (token: InputToken): CSSObject => {
// ========================= Input ========================= // ========================= Input =========================
[`${componentCls}-clear-icon`]: { [`${componentCls}-clear-icon`]: {
margin: 0, margin: 0,
padding: 0,
lineHeight: 0, lineHeight: 0,
color: token.colorTextQuaternary, color: token.colorTextQuaternary,
fontSize: token.fontSizeIcon, fontSize: token.fontSizeIcon,

View File

@ -1405,7 +1405,7 @@ exports[`renders components/layout/demo/fixed-sider.tsx extend context correctly
> >
<aside <aside
class="ant-layout-sider ant-layout-sider-dark" class="ant-layout-sider ant-layout-sider-dark"
style="overflow: auto; height: 100vh; position: fixed; inset-inline-start: 0; top: 0px; bottom: 0px; flex: 0 0 200px; max-width: 200px; min-width: 200px; width: 200px;" style="overflow: auto; height: 100vh; position: sticky; inset-inline-start: 0; top: 0px; bottom: 0px; flex: 0 0 200px; max-width: 200px; min-width: 200px; width: 200px;"
> >
<div <div
class="ant-layout-sider-children" class="ant-layout-sider-children"
@ -1836,7 +1836,6 @@ exports[`renders components/layout/demo/fixed-sider.tsx extend context correctly
</aside> </aside>
<div <div
class="ant-layout" class="ant-layout"
style="margin-inline-start: 200px;"
> >
<header <header
class="ant-layout-header" class="ant-layout-header"

View File

@ -765,7 +765,7 @@ exports[`renders components/layout/demo/fixed-sider.tsx correctly 1`] = `
> >
<aside <aside
class="ant-layout-sider ant-layout-sider-dark" class="ant-layout-sider ant-layout-sider-dark"
style="overflow:auto;height:100vh;position:fixed;inset-inline-start:0;top:0;bottom:0;scrollbar-width:thin;scrollbar-gutter:stable;flex:0 0 200px;max-width:200px;min-width:200px;width:200px" style="overflow:auto;height:100vh;position:sticky;inset-inline-start:0;top:0;bottom:0;scrollbar-width:thin;scrollbar-gutter:stable;flex:0 0 200px;max-width:200px;min-width:200px;width:200px"
> >
<div <div
class="ant-layout-sider-children" class="ant-layout-sider-children"
@ -1044,7 +1044,6 @@ exports[`renders components/layout/demo/fixed-sider.tsx correctly 1`] = `
</aside> </aside>
<div <div
class="ant-layout" class="ant-layout"
style="margin-inline-start:200px"
> >
<header <header
class="ant-layout-header" class="ant-layout-header"

View File

@ -4,4 +4,4 @@
## en-US ## en-US
When dealing with long content, a fixed sider can provide a better user experience. When dealing with long content, a sticky sider can provide a better user experience.

View File

@ -17,7 +17,7 @@ const { Header, Content, Footer, Sider } = Layout;
const siderStyle: React.CSSProperties = { const siderStyle: React.CSSProperties = {
overflow: 'auto', overflow: 'auto',
height: '100vh', height: '100vh',
position: 'fixed', position: 'sticky',
insetInlineStart: 0, insetInlineStart: 0,
top: 0, top: 0,
bottom: 0, bottom: 0,
@ -51,7 +51,7 @@ const App: React.FC = () => {
<div className="demo-logo-vertical" /> <div className="demo-logo-vertical" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={['4']} items={items} /> <Menu theme="dark" mode="inline" defaultSelectedKeys={['4']} items={items} />
</Sider> </Sider>
<Layout style={{ marginInlineStart: 200 }}> <Layout>
<Header style={{ padding: 0, background: colorBgContainer }} /> <Header style={{ padding: 0, background: colorBgContainer }} />
<Content style={{ margin: '24px 16px 0', overflow: 'initial' }}> <Content style={{ margin: '24px 16px 0', overflow: 'initial' }}>
<div <div

View File

@ -4,4 +4,4 @@
## en-US ## en-US
Fixed Header is generally used to fix the top navigation to facilitate page switching. Sticky Header is generally used to fix the top navigation to facilitate page switching.

View File

@ -126,6 +126,7 @@ const genMentionsStyle: GenerateStyle<MentionsToken> = (token) => {
insetBlockStart: calc(fontSize).mul(lineHeight).mul(0.5).add(paddingBlock).equal(), insetBlockStart: calc(fontSize).mul(lineHeight).mul(0.5).add(paddingBlock).equal(),
transform: `translateY(-50%)`, transform: `translateY(-50%)`,
margin: 0, margin: 0,
padding: 0,
color: colorTextQuaternary, color: colorTextQuaternary,
fontSize: fontSizeIcon, fontSize: fontSizeIcon,
verticalAlign: -1, verticalAlign: -1,

View File

@ -1924,6 +1924,40 @@ exports[`renders components/menu/demo/extra-style.tsx extend context correctly 1
/> />
</div> </div>
</div> </div>
<li
aria-disabled="true"
class="ant-menu-item ant-menu-item-disabled ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-3"
role="menuitem"
style="padding-left: 48px;"
>
<span
class="ant-menu-title-content"
>
<a
href="https://www.baidu.com"
>
Link Option
</a>
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</ul> </ul>
</div> </div>
<ul <ul
@ -2026,6 +2060,40 @@ exports[`renders components/menu/demo/extra-style.tsx extend context correctly 1
/> />
</div> </div>
</div> </div>
<li
aria-disabled="true"
class="ant-menu-item ant-menu-item-disabled ant-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-3"
role="menuitem"
style="padding-left: 48px;"
>
<span
class="ant-menu-title-content"
>
<a
href="https://www.baidu.com"
>
Link Option
</a>
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</ul> </ul>
</li> </li>
</ul> </ul>

View File

@ -911,6 +911,22 @@ exports[`renders components/menu/demo/extra-style.tsx correctly 1`] = `
</span> </span>
</span> </span>
</li> </li>
<li
aria-disabled="true"
class="ant-menu-item ant-menu-item-disabled ant-menu-item-only-child"
role="menuitem"
style="padding-left:48px"
>
<span
class="ant-menu-title-content"
>
<a
href="https://www.baidu.com"
>
Link Option
</a>
</span>
</li>
</ul> </ul>
</li> </li>
</ul> </ul>

View File

@ -1165,4 +1165,32 @@ describe('Menu', () => {
expect(container.querySelector('.ant-menu-title-content-with-extra')).toBeInTheDocument(); expect(container.querySelector('.ant-menu-title-content-with-extra')).toBeInTheDocument();
expect(container.querySelector('.ant-menu-item-extra')?.textContent).toBe(text); expect(container.querySelector('.ant-menu-item-extra')?.textContent).toBe(text);
}); });
it('should prevent click events when disabled MenuItem with link', () => {
const onClick = jest.fn();
const { container } = render(
<Menu
mode="vertical"
items={[
{
key: '1',
disabled: true,
label: (
<a href="https://ant.design" onClick={onClick}>
Disabled Link
</a>
),
},
]}
/>,
);
const link = container.querySelector('a')!;
expect(container.querySelector('.ant-menu-item')).toHaveClass('ant-menu-item-disabled');
expect(window.getComputedStyle(link).pointerEvents).toBe('none');
expect(link).toHaveStyle({
pointerEvents: 'none',
cursor: 'not-allowed',
});
});
}); });

View File

@ -25,6 +25,11 @@ const items1: MenuItem[] = [
label: 'Option 2', label: 'Option 2',
extra: '⌘P', extra: '⌘P',
}, },
{
key: '3',
label: <a href="https://www.baidu.com">Link Option</a>,
disabled: true,
},
], ],
}, },
]; ];

View File

@ -474,6 +474,8 @@ const genMenuItemStyle = (token: MenuToken): CSSObject => {
a: { a: {
color: 'inherit !important', color: 'inherit !important',
cursor: 'not-allowed',
pointerEvents: 'none',
}, },
[`> ${componentCls}-submenu-title`]: { [`> ${componentCls}-submenu-title`]: {

View File

@ -59,7 +59,7 @@ The properties of config are as follows:
| icon | Customized icon | ReactNode | - | - | | icon | Customized icon | ReactNode | - | - |
| key | The unique identifier of the Notification | string | - | - | | key | The unique identifier of the Notification | string | - | - |
| message | The title of notification box (required) | ReactNode | - | - | | message | The title of notification box (required) | ReactNode | - | - |
| placement | Position of Notification, can be one of `top` `topLeft` `topRight` `bottom` `bottomLeft` `bottomRight` | string | `topRight` | - | | placement | Position of Notification, can be one of `top` \| `topLeft` \| `topRight` \| `bottom` \| `bottomLeft` \| `bottomRight` | string | `topRight` | - |
| style | Customized inline style | [CSSProperties](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e434515761b36830c3e58a970abf5186f005adac/types/react/index.d.ts#L794) | - | - | | style | Customized inline style | [CSSProperties](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e434515761b36830c3e58a970abf5186f005adac/types/react/index.d.ts#L794) | - | - |
| role | The semantics of notification content recognized by screen readers. The default value is `alert`. When set as the default value, the screen reader will promptly interrupt any ongoing content reading and prioritize the notification content for immediate attention. | `alert \| status` | `alert` | 5.6.0 | | role | The semantics of notification content recognized by screen readers. The default value is `alert`. When set as the default value, the screen reader will promptly interrupt any ongoing content reading and prioritize the notification content for immediate attention. | `alert \| status` | `alert` | 5.6.0 |
| onClick | Specify a function that will be called when the notification is clicked | function | - | - | | onClick | Specify a function that will be called when the notification is clicked | function | - | - |
@ -75,7 +75,7 @@ The properties of config are as follows:
| bottom | Distance from the bottom of the viewport, when `placement` is `bottom` `bottomRight` or `bottomLeft` (unit: pixels) | number | 24 | | | bottom | Distance from the bottom of the viewport, when `placement` is `bottom` `bottomRight` or `bottomLeft` (unit: pixels) | number | 24 | |
| closeIcon | Custom close icon | ReactNode | true | 5.7.0: close button will be hidden when setting to null or false | | closeIcon | Custom close icon | ReactNode | true | 5.7.0: close button will be hidden when setting to null or false |
| getContainer | Return the mount node for Notification | () => HTMLNode | () => document.body | | | getContainer | Return the mount node for Notification | () => HTMLNode | () => document.body | |
| placement | Position of Notification, can be one of `top` `topLeft` `topRight` `bottom` `bottomLeft` `bottomRight` | string | `topRight` | | | placement | Position of Notification, can be one of `top` \| `topLeft` \| `topRight` \| `bottom` \| `bottomLeft` \| `bottomRight` | string | `topRight` | |
| showProgress | Show progress bar for auto-closing notification | boolean | | 5.18.0 | | showProgress | Show progress bar for auto-closing notification | boolean | | 5.18.0 |
| pauseOnHover | keep the timer running or not on hover | boolean | true | 5.18.0 | | pauseOnHover | keep the timer running or not on hover | boolean | true | 5.18.0 |
| rtl | Whether to enable RTL mode | boolean | false | | | rtl | Whether to enable RTL mode | boolean | false | |

View File

@ -60,7 +60,7 @@ config 参数如下:
| icon | 自定义图标 | ReactNode | - | - | | icon | 自定义图标 | ReactNode | - | - |
| key | 当前通知唯一标志 | string | - | - | | key | 当前通知唯一标志 | string | - | - |
| message | 通知提醒标题,必选 | ReactNode | - | - | | message | 通知提醒标题,必选 | ReactNode | - | - |
| placement | 弹出位置,可选 `top` `topLeft` `topRight` `bottom` `bottomLeft` `bottomRight` | string | `topRight` | - | | placement | 弹出位置,可选 `top` \| `topLeft` \| `topRight` \| `bottom` \| `bottomLeft` \| `bottomRight` | string | `topRight` | - |
| style | 自定义内联样式 | [CSSProperties](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e434515761b36830c3e58a970abf5186f005adac/types/react/index.d.ts#L794) | - | - | | style | 自定义内联样式 | [CSSProperties](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e434515761b36830c3e58a970abf5186f005adac/types/react/index.d.ts#L794) | - | - |
| role | 供屏幕阅读器识别的通知内容语义,默认为 `alert`。此情况下屏幕阅读器会立即打断当前正在阅读的其他内容,转而阅读通知内容 | `alert \| status` | `alert` | 5.6.0 | | role | 供屏幕阅读器识别的通知内容语义,默认为 `alert`。此情况下屏幕阅读器会立即打断当前正在阅读的其他内容,转而阅读通知内容 | `alert \| status` | `alert` | 5.6.0 |
| onClick | 点击通知时触发的回调函数 | function | - | - | | onClick | 点击通知时触发的回调函数 | function | - | - |
@ -76,7 +76,7 @@ config 参数如下:
| bottom | 消息从底部弹出时,距离底部的位置,单位像素 | number | 24 | | | bottom | 消息从底部弹出时,距离底部的位置,单位像素 | number | 24 | |
| closeIcon | 自定义关闭图标 | ReactNode | true | 5.7.0:设置为 null 或 false 时隐藏关闭按钮 | | closeIcon | 自定义关闭图标 | ReactNode | true | 5.7.0:设置为 null 或 false 时隐藏关闭按钮 |
| getContainer | 配置渲染节点的输出位置 | () => HTMLNode | () => document.body | | | getContainer | 配置渲染节点的输出位置 | () => HTMLNode | () => document.body | |
| placement | 弹出位置,可选 `top` `topLeft` `topRight` `bottom` `bottomLeft` `bottomRight` | string | `topRight` | | | placement | 弹出位置,可选 `top` \| `topLeft` \| `topRight` \| `bottom` \| `bottomLeft` \| `bottomRight` | string | `topRight` | |
| showProgress | 显示自动关闭通知框的进度条 | boolean | | 5.18.0 | | showProgress | 显示自动关闭通知框的进度条 | boolean | | 5.18.0 |
| pauseOnHover | 悬停时是否暂停计时器 | boolean | true | 5.18.0 | | pauseOnHover | 悬停时是否暂停计时器 | boolean | true | 5.18.0 |
| rtl | 是否开启 RTL 模式 | boolean | false | | | rtl | 是否开启 RTL 模式 | boolean | false | |

View File

@ -1149,7 +1149,31 @@ exports[`renders components/radio/demo/radiogroup.tsx extend context correctly 1
<span <span
class="ant-radio-label" class="ant-radio-label"
> >
A <div
class="ant-flex ant-flex-align-center ant-flex-justify-center ant-flex-gap-small ant-flex-vertical"
>
<span
aria-label="line-chart"
class="anticon anticon-line-chart"
role="img"
style="font-size: 18px;"
>
<svg
aria-hidden="true"
data-icon="line-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M888 792H200V168c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v688c0 4.4 3.6 8 8 8h752c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM305.8 637.7c3.1 3.1 8.1 3.1 11.3 0l138.3-137.6L583 628.5c3.1 3.1 8.2 3.1 11.3 0l275.4-275.3c3.1-3.1 3.1-8.2 0-11.3l-39.6-39.6a8.03 8.03 0 00-11.3 0l-230 229.9L461.4 404a8.03 8.03 0 00-11.3 0L266.3 586.7a8.03 8.03 0 000 11.3l39.5 39.7z"
/>
</svg>
</span>
LineChart
</div>
</span> </span>
</label> </label>
<label <label
@ -1171,7 +1195,31 @@ exports[`renders components/radio/demo/radiogroup.tsx extend context correctly 1
<span <span
class="ant-radio-label" class="ant-radio-label"
> >
B <div
class="ant-flex ant-flex-align-center ant-flex-justify-center ant-flex-gap-small ant-flex-vertical"
>
<span
aria-label="dot-chart"
class="anticon anticon-dot-chart"
role="img"
style="font-size: 18px;"
>
<svg
aria-hidden="true"
data-icon="dot-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M888 792H200V168c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v688c0 4.4 3.6 8 8 8h752c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM288 604a64 64 0 10128 0 64 64 0 10-128 0zm118-224a48 48 0 1096 0 48 48 0 10-96 0zm158 228a96 96 0 10192 0 96 96 0 10-192 0zm148-314a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
DotChart
</div>
</span> </span>
</label> </label>
<label <label
@ -1193,7 +1241,31 @@ exports[`renders components/radio/demo/radiogroup.tsx extend context correctly 1
<span <span
class="ant-radio-label" class="ant-radio-label"
> >
C <div
class="ant-flex ant-flex-align-center ant-flex-justify-center ant-flex-gap-small ant-flex-vertical"
>
<span
aria-label="bar-chart"
class="anticon anticon-bar-chart"
role="img"
style="font-size: 18px;"
>
<svg
aria-hidden="true"
data-icon="bar-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M888 792H200V168c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v688c0 4.4 3.6 8 8 8h752c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm-600-80h56c4.4 0 8-3.6 8-8V560c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v144c0 4.4 3.6 8 8 8zm152 0h56c4.4 0 8-3.6 8-8V384c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v320c0 4.4 3.6 8 8 8zm152 0h56c4.4 0 8-3.6 8-8V462c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v242c0 4.4 3.6 8 8 8zm152 0h56c4.4 0 8-3.6 8-8V304c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v400c0 4.4 3.6 8 8 8z"
/>
</svg>
</span>
BarChart
</div>
</span> </span>
</label> </label>
<label <label
@ -1215,7 +1287,31 @@ exports[`renders components/radio/demo/radiogroup.tsx extend context correctly 1
<span <span
class="ant-radio-label" class="ant-radio-label"
> >
D <div
class="ant-flex ant-flex-align-center ant-flex-justify-center ant-flex-gap-small ant-flex-vertical"
>
<span
aria-label="pie-chart"
class="anticon anticon-pie-chart"
role="img"
style="font-size: 18px;"
>
<svg
aria-hidden="true"
data-icon="pie-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M864 518H506V160c0-4.4-3.6-8-8-8h-26a398.46 398.46 0 00-282.8 117.1 398.19 398.19 0 00-85.7 127.1A397.61 397.61 0 0072 552a398.46 398.46 0 00117.1 282.8c36.7 36.7 79.5 65.6 127.1 85.7A397.61 397.61 0 00472 952a398.46 398.46 0 00282.8-117.1c36.7-36.7 65.6-79.5 85.7-127.1A397.61 397.61 0 00872 552v-26c0-4.4-3.6-8-8-8zM705.7 787.8A331.59 331.59 0 01470.4 884c-88.1-.4-170.9-34.9-233.2-97.2C174.5 724.1 140 640.7 140 552c0-88.7 34.5-172.1 97.2-234.8 54.6-54.6 124.9-87.9 200.8-95.5V586h364.3c-7.7 76.3-41.3 147-96.6 201.8zM952 462.4l-2.6-28.2c-8.5-92.1-49.4-179-115.2-244.6A399.4 399.4 0 00589 74.6L560.7 72c-4.7-.4-8.7 3.2-8.7 7.9V464c0 4.4 3.6 8 8 8l384-1c4.7 0 8.4-4 8-8.6zm-332.2-58.2V147.6a332.24 332.24 0 01166.4 89.8c45.7 45.6 77 103.6 90 166.1l-256.4.7z"
/>
</svg>
</span>
PieChart
</div>
</span> </span>
</label> </label>
</div> </div>
@ -1448,116 +1544,97 @@ exports[`renders components/radio/demo/radiogroup-block.tsx extend context corre
exports[`renders components/radio/demo/radiogroup-more.tsx extend context correctly 1`] = ` exports[`renders components/radio/demo/radiogroup-more.tsx extend context correctly 1`] = `
<div <div
class="ant-radio-group ant-radio-group-outline" class="ant-radio-group ant-radio-group-outline"
style="display: flex; flex-direction: column; gap: 8px;"
> >
<div <label
class="ant-space ant-space-vertical ant-space-gap-row-small ant-space-gap-col-small" class="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<div <span
class="ant-space-item" class="ant-radio ant-wave-target ant-radio-checked"
> >
<label <input
class="ant-radio-wrapper ant-radio-wrapper-checked" checked=""
> class="ant-radio-input"
<span name="test-id"
class="ant-radio ant-wave-target ant-radio-checked" type="radio"
> value="1"
<input />
checked="" <span
class="ant-radio-input" class="ant-radio-inner"
name="test-id" />
type="radio" </span>
value="1" <span
/> class="ant-radio-label"
<span
class="ant-radio-inner"
/>
</span>
<span
class="ant-radio-label"
>
Option A
</span>
</label>
</div>
<div
class="ant-space-item"
> >
<label Option A
class="ant-radio-wrapper" </span>
> </label>
<span <label
class="ant-radio ant-wave-target" class="ant-radio-wrapper"
> >
<input <span
class="ant-radio-input" class="ant-radio ant-wave-target"
name="test-id"
type="radio"
value="2"
/>
<span
class="ant-radio-inner"
/>
</span>
<span
class="ant-radio-label"
>
Option B
</span>
</label>
</div>
<div
class="ant-space-item"
> >
<label <input
class="ant-radio-wrapper" class="ant-radio-input"
> name="test-id"
<span type="radio"
class="ant-radio ant-wave-target" value="2"
> />
<input <span
class="ant-radio-input" class="ant-radio-inner"
name="test-id" />
type="radio" </span>
value="3" <span
/> class="ant-radio-label"
<span
class="ant-radio-inner"
/>
</span>
<span
class="ant-radio-label"
>
Option C
</span>
</label>
</div>
<div
class="ant-space-item"
> >
<label Option B
class="ant-radio-wrapper" </span>
> </label>
<span <label
class="ant-radio ant-wave-target" class="ant-radio-wrapper"
> >
<input <span
class="ant-radio-input" class="ant-radio ant-wave-target"
name="test-id" >
type="radio" <input
value="4" class="ant-radio-input"
/> name="test-id"
<span type="radio"
class="ant-radio-inner" value="3"
/> />
</span> <span
<span class="ant-radio-inner"
class="ant-radio-label" />
> </span>
More... <span
</span> class="ant-radio-label"
</label> >
</div> Option C
</div> </span>
</label>
<label
class="ant-radio-wrapper"
>
<span
class="ant-radio ant-wave-target"
>
<input
class="ant-radio-input"
name="test-id"
type="radio"
value="4"
/>
<span
class="ant-radio-inner"
/>
</span>
<span
class="ant-radio-label"
>
More...
</span>
</label>
</div> </div>
`; `;

View File

@ -1135,7 +1135,31 @@ exports[`renders components/radio/demo/radiogroup.tsx correctly 1`] = `
<span <span
class="ant-radio-label" class="ant-radio-label"
> >
A <div
class="ant-flex ant-flex-align-center ant-flex-justify-center ant-flex-gap-small ant-flex-vertical"
>
<span
aria-label="line-chart"
class="anticon anticon-line-chart"
role="img"
style="font-size:18px"
>
<svg
aria-hidden="true"
data-icon="line-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M888 792H200V168c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v688c0 4.4 3.6 8 8 8h752c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM305.8 637.7c3.1 3.1 8.1 3.1 11.3 0l138.3-137.6L583 628.5c3.1 3.1 8.2 3.1 11.3 0l275.4-275.3c3.1-3.1 3.1-8.2 0-11.3l-39.6-39.6a8.03 8.03 0 00-11.3 0l-230 229.9L461.4 404a8.03 8.03 0 00-11.3 0L266.3 586.7a8.03 8.03 0 000 11.3l39.5 39.7z"
/>
</svg>
</span>
LineChart
</div>
</span> </span>
</label> </label>
<label <label
@ -1157,7 +1181,31 @@ exports[`renders components/radio/demo/radiogroup.tsx correctly 1`] = `
<span <span
class="ant-radio-label" class="ant-radio-label"
> >
B <div
class="ant-flex ant-flex-align-center ant-flex-justify-center ant-flex-gap-small ant-flex-vertical"
>
<span
aria-label="dot-chart"
class="anticon anticon-dot-chart"
role="img"
style="font-size:18px"
>
<svg
aria-hidden="true"
data-icon="dot-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M888 792H200V168c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v688c0 4.4 3.6 8 8 8h752c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM288 604a64 64 0 10128 0 64 64 0 10-128 0zm118-224a48 48 0 1096 0 48 48 0 10-96 0zm158 228a96 96 0 10192 0 96 96 0 10-192 0zm148-314a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
DotChart
</div>
</span> </span>
</label> </label>
<label <label
@ -1179,7 +1227,31 @@ exports[`renders components/radio/demo/radiogroup.tsx correctly 1`] = `
<span <span
class="ant-radio-label" class="ant-radio-label"
> >
C <div
class="ant-flex ant-flex-align-center ant-flex-justify-center ant-flex-gap-small ant-flex-vertical"
>
<span
aria-label="bar-chart"
class="anticon anticon-bar-chart"
role="img"
style="font-size:18px"
>
<svg
aria-hidden="true"
data-icon="bar-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M888 792H200V168c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v688c0 4.4 3.6 8 8 8h752c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm-600-80h56c4.4 0 8-3.6 8-8V560c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v144c0 4.4 3.6 8 8 8zm152 0h56c4.4 0 8-3.6 8-8V384c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v320c0 4.4 3.6 8 8 8zm152 0h56c4.4 0 8-3.6 8-8V462c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v242c0 4.4 3.6 8 8 8zm152 0h56c4.4 0 8-3.6 8-8V304c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v400c0 4.4 3.6 8 8 8z"
/>
</svg>
</span>
BarChart
</div>
</span> </span>
</label> </label>
<label <label
@ -1201,7 +1273,31 @@ exports[`renders components/radio/demo/radiogroup.tsx correctly 1`] = `
<span <span
class="ant-radio-label" class="ant-radio-label"
> >
D <div
class="ant-flex ant-flex-align-center ant-flex-justify-center ant-flex-gap-small ant-flex-vertical"
>
<span
aria-label="pie-chart"
class="anticon anticon-pie-chart"
role="img"
style="font-size:18px"
>
<svg
aria-hidden="true"
data-icon="pie-chart"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M864 518H506V160c0-4.4-3.6-8-8-8h-26a398.46 398.46 0 00-282.8 117.1 398.19 398.19 0 00-85.7 127.1A397.61 397.61 0 0072 552a398.46 398.46 0 00117.1 282.8c36.7 36.7 79.5 65.6 127.1 85.7A397.61 397.61 0 00472 952a398.46 398.46 0 00282.8-117.1c36.7-36.7 65.6-79.5 85.7-127.1A397.61 397.61 0 00872 552v-26c0-4.4-3.6-8-8-8zM705.7 787.8A331.59 331.59 0 01470.4 884c-88.1-.4-170.9-34.9-233.2-97.2C174.5 724.1 140 640.7 140 552c0-88.7 34.5-172.1 97.2-234.8 54.6-54.6 124.9-87.9 200.8-95.5V586h364.3c-7.7 76.3-41.3 147-96.6 201.8zM952 462.4l-2.6-28.2c-8.5-92.1-49.4-179-115.2-244.6A399.4 399.4 0 00589 74.6L560.7 72c-4.7-.4-8.7 3.2-8.7 7.9V464c0 4.4 3.6 8 8 8l384-1c4.7 0 8.4-4 8-8.6zm-332.2-58.2V147.6a332.24 332.24 0 01166.4 89.8c45.7 45.6 77 103.6 90 166.1l-256.4.7z"
/>
</svg>
</span>
PieChart
</div>
</span> </span>
</label> </label>
</div> </div>
@ -1430,116 +1526,97 @@ exports[`renders components/radio/demo/radiogroup-block.tsx correctly 1`] = `
exports[`renders components/radio/demo/radiogroup-more.tsx correctly 1`] = ` exports[`renders components/radio/demo/radiogroup-more.tsx correctly 1`] = `
<div <div
class="ant-radio-group ant-radio-group-outline" class="ant-radio-group ant-radio-group-outline"
style="display:flex;flex-direction:column;gap:8px"
> >
<div <label
class="ant-space ant-space-vertical ant-space-gap-row-small ant-space-gap-col-small" class="ant-radio-wrapper ant-radio-wrapper-checked"
> >
<div <span
class="ant-space-item" class="ant-radio ant-wave-target ant-radio-checked"
> >
<label <input
class="ant-radio-wrapper ant-radio-wrapper-checked" checked=""
> class="ant-radio-input"
<span name="test-id"
class="ant-radio ant-wave-target ant-radio-checked" type="radio"
> value="1"
<input />
checked="" <span
class="ant-radio-input" class="ant-radio-inner"
name="test-id" />
type="radio" </span>
value="1" <span
/> class="ant-radio-label"
<span
class="ant-radio-inner"
/>
</span>
<span
class="ant-radio-label"
>
Option A
</span>
</label>
</div>
<div
class="ant-space-item"
> >
<label Option A
class="ant-radio-wrapper" </span>
> </label>
<span <label
class="ant-radio ant-wave-target" class="ant-radio-wrapper"
> >
<input <span
class="ant-radio-input" class="ant-radio ant-wave-target"
name="test-id"
type="radio"
value="2"
/>
<span
class="ant-radio-inner"
/>
</span>
<span
class="ant-radio-label"
>
Option B
</span>
</label>
</div>
<div
class="ant-space-item"
> >
<label <input
class="ant-radio-wrapper" class="ant-radio-input"
> name="test-id"
<span type="radio"
class="ant-radio ant-wave-target" value="2"
> />
<input <span
class="ant-radio-input" class="ant-radio-inner"
name="test-id" />
type="radio" </span>
value="3" <span
/> class="ant-radio-label"
<span
class="ant-radio-inner"
/>
</span>
<span
class="ant-radio-label"
>
Option C
</span>
</label>
</div>
<div
class="ant-space-item"
> >
<label Option B
class="ant-radio-wrapper" </span>
> </label>
<span <label
class="ant-radio ant-wave-target" class="ant-radio-wrapper"
> >
<input <span
class="ant-radio-input" class="ant-radio ant-wave-target"
name="test-id" >
type="radio" <input
value="4" class="ant-radio-input"
/> name="test-id"
<span type="radio"
class="ant-radio-inner" value="3"
/> />
</span> <span
<span class="ant-radio-inner"
class="ant-radio-label" />
> </span>
More... <span
</span> class="ant-radio-label"
</label> >
</div> Option C
</div> </span>
</label>
<label
class="ant-radio-wrapper"
>
<span
class="ant-radio ant-wave-target"
>
<input
class="ant-radio-input"
name="test-id"
type="radio"
value="4"
/>
<span
class="ant-radio-inner"
/>
</span>
<span
class="ant-radio-label"
>
More...
</span>
</label>
</div> </div>
`; `;

View File

@ -1,7 +1,8 @@
import React from 'react'; import React from 'react';
import { Flex, Radio } from 'antd'; import { Flex, Radio } from 'antd';
import type { CheckboxGroupProps } from 'antd/es/checkbox';
const options = [ const options: CheckboxGroupProps<string>['options'] = [
{ label: 'Apple', value: 'Apple' }, { label: 'Apple', value: 'Apple' },
{ label: 'Pear', value: 'Pear' }, { label: 'Pear', value: 'Pear' },
{ label: 'Orange', value: 'Orange' }, { label: 'Orange', value: 'Orange' },

View File

@ -1,27 +1,46 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import type { RadioChangeEvent } from 'antd'; import type { RadioChangeEvent } from 'antd';
import { Input, Radio, Space } from 'antd'; import { Input, Radio } from 'antd';
const style: React.CSSProperties = {
display: 'flex',
flexDirection: 'column',
gap: 8,
};
const App: React.FC = () => { const App: React.FC = () => {
const [value, setValue] = useState(1); const [value, setValue] = useState(1);
const onChange = (e: RadioChangeEvent) => { const onChange = (e: RadioChangeEvent) => {
console.log('radio checked', e.target.value);
setValue(e.target.value); setValue(e.target.value);
}; };
return ( return (
<Radio.Group onChange={onChange} value={value}> <Radio.Group
<Space direction="vertical"> style={style}
<Radio value={1}>Option A</Radio> onChange={onChange}
<Radio value={2}>Option B</Radio> value={value}
<Radio value={3}>Option C</Radio> options={[
<Radio value={4}> { value: 1, label: 'Option A' },
More... { value: 2, label: 'Option B' },
{value === 4 ? <Input style={{ width: 100, marginInlineStart: 10 }} /> : null} { value: 3, label: 'Option C' },
</Radio> {
</Space> value: 4,
</Radio.Group> label: (
<>
More...
{value === 4 && (
<Input
variant="filled"
placeholder="please input"
style={{ width: 120, marginInlineStart: 12 }}
/>
)}
</>
),
},
]}
/>
); );
}; };

View File

@ -1,14 +1,17 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import type { RadioChangeEvent } from 'antd'; import type { RadioChangeEvent } from 'antd';
import { Radio } from 'antd'; import { Radio } from 'antd';
import type { CheckboxGroupProps } from 'antd/es/checkbox';
const plainOptions = ['Apple', 'Pear', 'Orange']; const plainOptions: CheckboxGroupProps<string>['options'] = ['Apple', 'Pear', 'Orange'];
const options = [
const options: CheckboxGroupProps<string>['options'] = [
{ label: 'Apple', value: 'Apple' }, { label: 'Apple', value: 'Apple' },
{ label: 'Pear', value: 'Pear' }, { label: 'Pear', value: 'Pear' },
{ label: 'Orange', value: 'Orange', title: 'Orange' }, { label: 'Orange', value: 'Orange', title: 'Orange' },
]; ];
const optionsWithDisabled = [
const optionsWithDisabled: CheckboxGroupProps<string>['options'] = [
{ label: 'Apple', value: 'Apple' }, { label: 'Apple', value: 'Apple' },
{ label: 'Pear', value: 'Pear' }, { label: 'Pear', value: 'Pear' },
{ label: 'Orange', value: 'Orange', disabled: true }, { label: 'Orange', value: 'Orange', disabled: true },

View File

@ -2,12 +2,16 @@ import React from 'react';
import { Radio } from 'antd'; import { Radio } from 'antd';
const App: React.FC = () => ( const App: React.FC = () => (
<Radio.Group name="radiogroup" defaultValue={1}> <Radio.Group
<Radio value={1}>A</Radio> name="radiogroup"
<Radio value={2}>B</Radio> defaultValue={1}
<Radio value={3}>C</Radio> options={[
<Radio value={4}>D</Radio> { value: 1, label: 'A' },
</Radio.Group> { value: 2, label: 'B' },
{ value: 3, label: 'C' },
{ value: 4, label: 'D' },
]}
/>
); );
export default App; export default App;

View File

@ -1,22 +1,63 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import {
BarChartOutlined,
DotChartOutlined,
LineChartOutlined,
PieChartOutlined,
} from '@ant-design/icons';
import type { RadioChangeEvent } from 'antd'; import type { RadioChangeEvent } from 'antd';
import { Radio } from 'antd'; import { Flex, Radio } from 'antd';
const App: React.FC = () => { const App: React.FC = () => {
const [value, setValue] = useState(1); const [value, setValue] = useState(1);
const onChange = (e: RadioChangeEvent) => { const onChange = (e: RadioChangeEvent) => {
console.log('radio checked', e.target.value);
setValue(e.target.value); setValue(e.target.value);
}; };
return ( return (
<Radio.Group onChange={onChange} value={value}> <Radio.Group
<Radio value={1}>A</Radio> onChange={onChange}
<Radio value={2}>B</Radio> value={value}
<Radio value={3}>C</Radio> options={[
<Radio value={4}>D</Radio> {
</Radio.Group> value: 1,
label: (
<Flex gap="small" justify="center" align="center" vertical>
<LineChartOutlined style={{ fontSize: 18 }} />
LineChart
</Flex>
),
},
{
value: 2,
label: (
<Flex gap="small" justify="center" align="center" vertical>
<DotChartOutlined style={{ fontSize: 18 }} />
DotChart
</Flex>
),
},
{
value: 3,
label: (
<Flex gap="small" justify="center" align="center" vertical>
<BarChartOutlined style={{ fontSize: 18 }} />
BarChart
</Flex>
),
},
{
value: 4,
label: (
<Flex gap="small" justify="center" align="center" vertical>
<PieChartOutlined style={{ fontSize: 18 }} />
PieChart
</Flex>
),
},
]}
/>
); );
}; };

View File

@ -1,21 +1,19 @@
import React from 'react'; import React from 'react';
import { ConfigProvider, Radio } from 'antd'; import { ConfigProvider, Radio } from 'antd';
import type { CheckboxGroupProps } from 'antd/es/checkbox';
const options: CheckboxGroupProps<string | number>['options'] = [
{ value: 1, label: 'A' },
{ value: 2, label: 'B' },
{ value: 3, label: 'C' },
{ value: 4, label: 'D' },
];
const App: React.FC = () => ( const App: React.FC = () => (
<ConfigProvider theme={{ token: { wireframe: true } }}> <ConfigProvider theme={{ token: { wireframe: true } }}>
<Radio.Group value={1}> <Radio.Group value={1} options={options} />
<Radio value={1}>A</Radio>
<Radio value={2}>B</Radio>
<Radio value={3}>C</Radio>
<Radio value={4}>D</Radio>
</Radio.Group>
<br /> <br />
<Radio.Group value={1} disabled> <Radio.Group value={1} options={options} disabled />
<Radio value={1}>A</Radio>
<Radio value={2}>B</Radio>
<Radio value={3}>C</Radio>
<Radio value={4}>D</Radio>
</Radio.Group>
</ConfigProvider> </ConfigProvider>
); );

View File

@ -14,6 +14,29 @@ demo:
- Used to select a single state from multiple options. - Used to select a single state from multiple options.
- The difference from Select is that Radio is visible to the user and can facilitate the comparison of choice, which means there shouldn't be too many of them. - The difference from Select is that Radio is visible to the user and can facilitate the comparison of choice, which means there shouldn't be too many of them.
```tsx
// When use Radio.Group, recommended ✅
return (
<Radio.Group
value={value}
options={[
{ value: 1, label: "A" },
{ value: 2, label: "B"},
{ value: 3, label: "C" },
]}
/>
);
// No recommended 🙅🏻‍♀️
return (
<Radio.Group value={value}>
<Radio value={1}>A</Radio>
<Radio value={2}>B</Radio>
<Radio value={3}>C</Radio>
</Radio.Group>
);
```
## Examples ## Examples
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->

View File

@ -15,6 +15,29 @@ demo:
- 用于在多个备选项中选中单个状态。 - 用于在多个备选项中选中单个状态。
- 和 Select 的区别是Radio 所有选项默认可见,方便用户在比较中选择,因此选项不宜过多。 - 和 Select 的区别是Radio 所有选项默认可见,方便用户在比较中选择,因此选项不宜过多。
```tsx
// 使用 Radio.Group 组件时,推荐的写法 ✅
return (
<Radio.Group
value={value}
options={[
{ value: 1, label: "A" },
{ value: 2, label: "B"},
{ value: 3, label: "C" },
]}
/>
);
// 不推荐的写法 🙅🏻‍♀️
return (
<Radio.Group value={value}>
<Radio value={1}>A</Radio>
<Radio value={2}>B</Radio>
<Radio value={3}>C</Radio>
</Radio.Group>
);
```
## 代码演示 ## 代码演示
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->

View File

@ -172,6 +172,10 @@ const getRadioBasicStyle: GenerateStyle<RadioToken> = (token) => {
marginInlineEnd: wrapperMarginInlineEnd, marginInlineEnd: wrapperMarginInlineEnd,
cursor: 'pointer', cursor: 'pointer',
'&:last-child': {
marginInlineEnd: 0,
},
// RTL // RTL
[`&${componentCls}-wrapper-rtl`]: { [`&${componentCls}-wrapper-rtl`]: {
direction: 'rtl', direction: 'rtl',

View File

@ -5,7 +5,7 @@ import { resetComponent } from '../../style';
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal'; import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
import { genStyleHooks, mergeToken } from '../../theme/internal'; import { genStyleHooks, mergeToken } from '../../theme/internal';
export type ComponentToken = { export interface ComponentToken {
/** /**
* @desc * @desc
* @descEN Star color * @descEN Star color
@ -26,7 +26,7 @@ export type ComponentToken = {
* @descEN Star background color * @descEN Star background color
*/ */
starBg: string; starBg: string;
}; }
interface RateToken extends FullToken<'Rate'> {} interface RateToken extends FullToken<'Rate'> {}

View File

@ -4,7 +4,7 @@ import { Keyframes, unit } from '@ant-design/cssinjs';
import type { CSSUtil, FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal'; import type { CSSUtil, FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
import { genStyleHooks, mergeToken } from '../../theme/internal'; import { genStyleHooks, mergeToken } from '../../theme/internal';
export type ComponentToken = { export interface ComponentToken {
/** @deprecated use gradientFromColor instead. */ /** @deprecated use gradientFromColor instead. */
color: string; color: string;
/** @deprecated use gradientToColor instead. */ /** @deprecated use gradientToColor instead. */
@ -39,7 +39,7 @@ export type ComponentToken = {
* @descEN Line height of paragraph skeleton * @descEN Line height of paragraph skeleton
*/ */
paragraphLiHeight: number; paragraphLiHeight: number;
}; }
const skeletonClsLoading = new Keyframes(`ant-skeleton-loading`, { const skeletonClsLoading = new Keyframes(`ant-skeleton-loading`, {
'0%': { '0%': {

View File

@ -557,18 +557,18 @@ const InternalTable = <RecordType extends AnyObject = AnyObject>(
const virtualProps: { listItemHeight?: number } = {}; const virtualProps: { listItemHeight?: number } = {};
const listItemHeight = React.useMemo(() => { const listItemHeight = React.useMemo(() => {
const { fontSize, lineHeight, padding, paddingXS, paddingSM } = token; const { fontSize, lineHeight, lineWidth, padding, paddingXS, paddingSM } = token;
const fontHeight = Math.floor(fontSize * lineHeight); const fontHeight = Math.floor(fontSize * lineHeight);
switch (mergedSize) { switch (mergedSize) {
case 'large': case 'middle':
return padding * 2 + fontHeight; return paddingSM * 2 + fontHeight + lineWidth;
case 'small': case 'small':
return paddingXS * 2 + fontHeight; return paddingXS * 2 + fontHeight + lineWidth;
default: default:
return paddingSM * 2 + fontHeight; return padding * 2 + fontHeight + lineWidth;
} }
}, [token, mergedSize]); }, [token, mergedSize]);

View File

@ -61,6 +61,7 @@
"Amir M. Mohamadi", "Amir M. Mohamadi",
"Amorites", "Amorites",
"Amour1688", "Amour1688",
"Amumu",
"Anas Tawfeek", "Anas Tawfeek",
"Andre Perunicic", "Andre Perunicic",
"Andre Zyczkowski", "Andre Zyczkowski",
@ -648,6 +649,7 @@
"Maximilian Meyer", "Maximilian Meyer",
"Mayowa Sogbein", "Mayowa Sogbein",
"Md_ZubairAhmed", "Md_ZubairAhmed",
"Mehmet Salih Yavuz",
"MeiLin", "MeiLin",
"MengZhaoFly", "MengZhaoFly",
"Meow-z", "Meow-z",
@ -698,6 +700,7 @@
"Muhammad Sameer", "Muhammad Sameer",
"Muhammad Sohaib Raza", "Muhammad Sohaib Raza",
"MuxinFeng", "MuxinFeng",
"MyeongHyun Lew",
"Mykyta Velykanov", "Mykyta Velykanov",
"Mário Gonçalves", "Mário Gonçalves",
"Nariman Movaffaghi", "Nariman Movaffaghi",
@ -748,6 +751,8 @@
"Oren Kosto", "Oren Kosto",
"Orkhan Huseynli", "Orkhan Huseynli",
"OuYancey", "OuYancey",
"OweQian",
"Oyster Lee",
"PCCCCCCC", "PCCCCCCC",
"Pablo Recalde", "Pablo Recalde",
"Panjie Setiawan Wicaksono", "Panjie Setiawan Wicaksono",
@ -822,6 +827,7 @@
"Rodrigo Ehlers", "Rodrigo Ehlers",
"Rohan Bagchi", "Rohan Bagchi",
"Rohan Malhotra", "Rohan Malhotra",
"Roman Donchenko",
"Roman Soroka", "Roman Soroka",
"Ron Šmeral", "Ron Šmeral",
"Rongjian Zhang", "Rongjian Zhang",
@ -845,6 +851,7 @@
"Sam Lanning", "Sam Lanning",
"Sam Marks", "Sam Marks",
"Sam Maxwell", "Sam Maxwell",
"SamLee",
"Samed Düzçay", "Samed Düzçay",
"Sami Mäkinen", "Sami Mäkinen",
"Samuel Gaus", "Samuel Gaus",
@ -1557,7 +1564,6 @@
"yoshinyan", "yoshinyan",
"youmoo", "youmoo",
"youngz", "youngz",
"yoyo837",
"yuanliu", "yuanliu",
"yuche", "yuche",
"yuezk", "yuezk",
@ -1681,6 +1687,7 @@
"栗康", "栗康",
"梓安", "梓安",
"沐霖", "沐霖",
"火尧",
"炒米粉", "炒米粉",
"烽宁", "烽宁",
"爱but的苍蝇", "爱but的苍蝇",

View File

@ -101,7 +101,13 @@ const miscKeys = [
// Changelog map // Changelog map
const componentChangelog: Record< const componentChangelog: Record<
string, string,
{ version: string; changelog: string; refs: string[]; releaseDate: string }[] {
version: string;
changelog: string;
refs: string[];
releaseDate: string;
contributors: string[];
}[]
> = {}; > = {};
Object.keys(componentNameMap).forEach((name) => { Object.keys(componentNameMap).forEach((name) => {
componentChangelog[name] = []; componentChangelog[name] = [];
@ -127,6 +133,20 @@ const miscKeys = [
lastReleaseDate = matchReleaseDate[1]; lastReleaseDate = matchReleaseDate[1];
} }
// Get Contributor name
const contributors: string[] = [];
const usernameMatches = line.match(/\[@([^\]]+)\]/g);
if (usernameMatches) {
usernameMatches.forEach((match) => {
const usernameMatch = match.match(/\[@([^\]]+)\]/);
if (usernameMatch) {
const username = usernameMatch[1];
contributors.push(username);
}
});
}
// Start when get version // Start when get version
if (!lastVersion) { if (!lastVersion) {
continue; continue;
@ -184,6 +204,7 @@ const miscKeys = [
changelog: changelogLine, changelog: changelogLine,
refs, refs,
releaseDate: lastReleaseDate, releaseDate: lastReleaseDate,
contributors,
}); });
matched = true; matched = true;
} }