Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions packages/x/.dumi/theme/builtins/Previewer/CodePreviewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import CodePenIcon from '../../icons/CodePenIcon';
import CodeSandboxIcon from '../../icons/CodeSandboxIcon';
import ExternalLinkIcon from '../../icons/ExternalLinkIcon';
import DemoContext from '../../slots/DemoContext';
import LiveError from '../../slots/LiveError';
import SiteContext from '../../slots/SiteContext';
import CodeBlockButton from './CodeBlockButton';
import type { AntdPreviewerProps } from './Previewer';
Expand All @@ -41,10 +42,12 @@ const track = ({ type, demo }: { type: string; demo: string }) => {
const useStyle = createStyles(({ token }) => {
const { borderRadius } = token;
return {
codeHideBtn: css`
stickyBox: css`
position: sticky;
bottom: 0;
z-index: 1;
`,
codeHideBtn: css`
width: 100%;
height: 40px;
display: flex;
Expand Down Expand Up @@ -518,18 +521,20 @@ fs.writeFileSync(path.join(dir, 'node.mjs'), content);
otherCode={otherCodeObject}
jsxCode={jsx}
styleCode={style}
error={liveDemoError}
entryName={entryName}
onSourceChange={setLiveDemoSource}
/>
<div
tabIndex={0}
role="button"
className={styles.codeHideBtn}
onClick={() => setCodeExpand(false)}
>
<UpOutlined />
<FormattedMessage id="app.demo.code.hide.simplify" />
<div className={styles.stickyBox}>
<LiveError error={liveDemoError} />
<div
tabIndex={0}
role="button"
className={styles.codeHideBtn}
onClick={() => setCodeExpand(false)}
>
<UpOutlined />
<FormattedMessage id="app.demo.code.hide.simplify" />
</div>
Comment on lines +530 to +537
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 验证该按钮是否仅有 role/tabIndex 但无键盘事件
rg -n -C2 'tabIndex=\{0\}|role="button"|onKeyDown=' packages/x/.dumi/theme/builtins/Previewer/CodePreviewer.tsx

Repository: ant-design/x

Length of output: 295


🏁 Script executed:

cat -n packages/x/.dumi/theme/builtins/Previewer/CodePreviewer.tsx | sed -n '525,545p'

Repository: ant-design/x

Length of output: 801


隐藏代码控件缺少键盘触发,存在可访问性缺口。

第 530-533 行使用了可聚焦的 divtabIndex={0} + role="button"),但缺少 onKeyDown 处理器,键盘用户无法通过 Enter/Space 键触发点击。建议改用原生 <button> 元素。

建议修改
-            <div
-              tabIndex={0}
-              role="button"
+            <button
+              type="button"
               className={styles.codeHideBtn}
               onClick={() => setCodeExpand(false)}
             >
               <UpOutlined />
               <FormattedMessage id="app.demo.code.hide.simplify" />
-            </div>
+            </button>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
tabIndex={0}
role="button"
className={styles.codeHideBtn}
onClick={() => setCodeExpand(false)}
>
<UpOutlined />
<FormattedMessage id="app.demo.code.hide.simplify" />
</div>
<button
type="button"
className={styles.codeHideBtn}
onClick={() => setCodeExpand(false)}
>
<UpOutlined />
<FormattedMessage id="app.demo.code.hide.simplify" />
</button>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/x/.dumi/theme/builtins/Previewer/CodePreviewer.tsx` around lines 530
- 537, The hide-control uses a focusable div with tabIndex and role but no
keyboard handler; update the CodePreviewer hide control (the element using
setCodeExpand(false) and styles.codeHideBtn) to be a native <button> (remove
tabIndex and role) so Enter/Space trigger works natively, preserve onClick and
children (<UpOutlined /> and FormattedMessage), and adjust CSS for
styles.codeHideBtn if needed to reset default button styles and maintain
layout/appearance.

</div>
</section>
)}
Expand Down
4 changes: 0 additions & 4 deletions packages/x/.dumi/theme/common/CodePreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ const CodePreview: React.FC<CodePreviewProps> = ({
styleCode = '',
entryName,
onSourceChange,
error,
}) => {
// 避免 Tabs 数量不稳定的闪动问题
const initialCodes: Partial<Record<'tsx' | 'jsx' | 'style', string>> = {};
Expand Down Expand Up @@ -156,7 +155,6 @@ const CodePreview: React.FC<CodePreviewProps> = ({
<div className={styles.code}>
{lang === 'tsx' ? (
<LiveCode
error={error}
lang={lang}
initialValue={sourceCodes[lang]}
onChange={(code: string) => {
Expand Down Expand Up @@ -184,7 +182,6 @@ const CodePreview: React.FC<CodePreviewProps> = ({
children: (
<div className={styles.code}>
<LiveCode
error={error}
lang={lang}
initialValue={codeString}
onChange={(code: string) => {
Expand All @@ -206,7 +203,6 @@ const CodePreview: React.FC<CodePreviewProps> = ({
if (langList.length === 1) {
return (
<LiveCode
error={error}
lang={langList[0]}
initialValue={sourceCodes[langList[0]]}
onChange={(code: string) => {
Expand Down
7 changes: 1 addition & 6 deletions packages/x/.dumi/theme/common/LiveCode.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import SourceCodeEditor from 'dumi/theme-default/slots/SourceCodeEditor';
import type { ComponentProps, FC } from 'react';
import React from 'react';

import LiveError from '../slots/LiveError';

const useStyle = createStyles(({ token, css }) => {
const { colorBgContainer } = token;
return {
Expand Down Expand Up @@ -51,9 +49,7 @@ const useStyle = createStyles(({ token, css }) => {
});

const LiveCode: FC<
{
error: Error | null;
} & Pick<ComponentProps<typeof SourceCodeEditor>, 'lang' | 'initialValue' | 'onChange'>
Pick<ComponentProps<typeof SourceCodeEditor>, 'lang' | 'initialValue' | 'onChange'>
> = (props) => {
const { styles } = useStyle();
return (
Expand All @@ -63,7 +59,6 @@ const LiveCode: FC<
initialValue={props.initialValue}
onChange={props.onChange}
/>
<LiveError error={props.error} />
</div>
);
};
Expand Down
6 changes: 3 additions & 3 deletions packages/x/.dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ export default defineConfig({
'@ant-design/x/lib': path.join(__dirname, 'components'),
'@ant-design/x/es': path.join(__dirname, 'components'),
'@ant-design/x': path.join(__dirname, 'components'),
'@ant-design/x-markdown': '../x-markdown/src',
'@ant-design/x-sdk': '../x-sdk/src',
'@ant-design/x-skill': '../x-skill/src',
'@ant-design/x-markdown': path.join(__dirname, '../x-markdown/src'),
'@ant-design/x-sdk': path.join(__dirname, '../x-sdk/src'),
'@ant-design/x-skill': path.join(__dirname, '../x-skill/src'),
// https://github.com/ant-design/ant-design/issues/46628
'@ant-design/icons$': '@ant-design/icons/lib',
},
Expand Down
5 changes: 3 additions & 2 deletions packages/x/docs/playground/agent-tbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -287,16 +287,17 @@ const useStyle = createStyles(({ token, css }) => {
}
`,
chatList: css`
flex: 1;
overflow-y: auto;
display: flex;
height: calc(100% - 120px);
flex-direction: column;
align-items: center;
width: 100%;
`,
placeholder: css`
padding-top: 32px;
width: 100%;
padding-inline: ${token.paddingLG}px;
padding: ${token.paddingLG}px;
box-sizing: border-box;
Comment on lines 298 to 301
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot Mar 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

padding-top 被后续 padding 覆盖,建议合并声明。

Line 298 的 padding-top: 32px 会被 Line 300 的 padding: ... 覆盖,当前顶部间距不是 32px。建议明确保留哪种间距,避免样式歧义。

💡 建议修改
     placeholder: css`
-      padding-top: 32px;
       width: 100%;
-      padding: ${token.paddingLG}px;
+      padding: ${token.paddingLG}px;
+      padding-top: 32px;
       box-sizing: border-box;
     `,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
padding-top: 32px;
width: 100%;
padding-inline: ${token.paddingLG}px;
padding: ${token.paddingLG}px;
box-sizing: border-box;
width: 100%;
padding: ${token.paddingLG}px;
padding-top: 32px;
box-sizing: border-box;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/x/docs/playground/agent-tbox.tsx` around lines 298 - 301,
当前样式块中同时使用了 `padding-top: 32px` 和后续的 `padding: ${token.paddingLG}px`,导致
`padding-top` 被覆盖;请在 agent-tbox.tsx 中的该样式块统一声明间距:要么删除 `padding-top: 32px` 并只保留
`padding: ${token.paddingLG}px`,要么把 32px 合并进 shorthand(例如将 shorthand 的 top 值替换为
32px),以消除歧义并确保顶部间距按预期生效(参考属性名:padding-top、padding、token.paddingLG)。

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

demo code短平快,保障样式没问题即可

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1uokun 理解,demo 代码以简洁实用为主,样式视觉效果没问题即可,不做强制要求。忽略此建议。


🧠 Learnings used
Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。

Learnt from: afc163
Repo: ant-design/x PR: 0
File: :0-0
Timestamp: 2025-04-11T14:47:09.527Z
Learning: 当评审 ant-design/x 仓库中的 PR 时,需要用中文回复中文评论。该项目的文档支持中英双语。

`,
// sender 样式
Expand Down
10 changes: 4 additions & 6 deletions packages/x/docs/playground/copilot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,17 @@ const useCopilotStyle = createStyles(({ token, css }) => {
`,
// chatList 样式
chatList: css`
flex:1;
overflow-y: auto;
padding-inline: 16px;
margin-block-start: ${token.margin}px;
display: flex;
height: calc(100% - 194px);
flex-direction: column;
`,
chatWelcome: css`
margin-inline: ${token.margin}px;
padding: 12px 16px;
border-radius: 2px 12px 12px 12px;
border-radius: 12px;
background: ${token.colorBgTextHover};
margin-bottom: ${token.margin}px;
`,
Expand Down Expand Up @@ -433,7 +435,6 @@ const Copilot = (props: CopilotProps) => {
/** 消息列表 */
<Bubble.List
ref={listRef}
style={{ paddingInline: 16 }}
items={messages?.map((i) => ({
...i.message,
key: i.id,
Expand All @@ -457,9 +458,6 @@ const Copilot = (props: CopilotProps) => {
title={locale.iCanHelp}
items={MOCK_QUESTIONS.map((i) => ({ key: i, description: i }))}
onItemClick={(info) => handleUserSubmit(info?.data?.description as string)}
style={{
marginInline: 16,
}}
Comment on lines 460 to -462
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Removing this inline marginInline style may cause a visual misalignment. The Welcome component above has a margin, but now this Prompts component will not, causing them to have different indentation levels. To maintain consistent alignment, consider re-adding a margin to this component, for example by applying a style class.

styles={{
title: { fontSize: 14 },
}}
Expand Down
9 changes: 4 additions & 5 deletions packages/x/docs/playground/independent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ const useStyle = createStyles(({ token, css }) => {
box-sizing: border-box;
display: flex;
flex-direction: column;
padding-block: ${token.paddingLG}px;
justify-content: space-between;
.ant-bubble-content-updating {
background-image: linear-gradient(90deg, #ff6b23 0%, #af3cb8 31%, #53b6ff 89%);
Expand All @@ -132,16 +131,16 @@ const useStyle = createStyles(({ token, css }) => {
}
`,
chatList: css`
flex: 1;
overflow-y: auto;
display: flex;
height: calc(100% - 120px);
flex-direction: column;
align-items: center;
width: 100%;
`,
placeholder: css`
padding-top: 32px;
width: 100%;
padding-inline: ${token.paddingLG}px;
padding: ${token.paddingLG}px;
box-sizing: border-box;
`,
// sender 样式
Expand Down Expand Up @@ -754,7 +753,7 @@ const Independent: React.FC = () => {
gap={12}
align="center"
style={{
marginInline: 24,
margin: 8,
}}
>
{/* 🌟 提示词 */}
Expand Down
115 changes: 52 additions & 63 deletions packages/x/docs/playground/ultramodern.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,20 +87,23 @@ const useStyle = createStyles(({ token, css }) => {
box-sizing: border-box;
display: flex;
flex-direction: column;
padding-block: ${token.paddingLG}px;
padding-inline: ${token.paddingLG}px;
gap: 16px;
.ant-bubble-content-updating {
background-image: linear-gradient(90deg, #ff6b23 0%, #af3cb8 31%, #53b6ff 89%);
background-size: 100% 2px;
background-repeat: no-repeat;
background-position: bottom;
}
`,
chatList: css`
flex: 1;
overflow-y: auto;
margin-block-start: ${token.margin}px;
`,
chatSender: css`
padding: ${token.paddingXS}px;
`,
Comment on lines +102 to +104
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The Sender component's container div.chatSender no longer has a maxWidth. This could result in the input area becoming excessively wide on larger screens, which is inconsistent with the maxWidth of the message bubbles above. To ensure a consistent layout, please add a maxWidth and center the element.

    chatSender: css`
      padding: ${token.paddingXS}px;
      width: 100%;
      max-width: 940px;
      margin-inline: auto;
    `,

startPage: css`
display: flex;
width: 100%;
max-width: 840px;
flex-direction: column;
align-items: center;
height: 100%;
Expand All @@ -111,14 +114,6 @@ const useStyle = createStyles(({ token, css }) => {
margin-block-end: 38px;
font-weight: 600;
`,
chatList: css`
display: flex;
align-items: center;
width: 100%;
height: 100%;
flex-direction: column;
justify-content: space-between;
`,
};
});

Expand Down Expand Up @@ -385,7 +380,6 @@ const App = () => {
styles={{
root: {
maxWidth: 940,
height: 'calc(100% - 160px)',
marginBlockEnd: 24,
},
}}
Expand All @@ -399,56 +393,51 @@ const App = () => {
role={getRole(className)}
/>
)}
<div
style={{ width: '100%', maxWidth: 840 }}
className={clsx({ [styles.startPage]: messages.length === 0 })}
>
{messages.length === 0 && (
<div className={styles.agentName}>{locale.agentName}</div>
)}
<Sender
suffix={false}
ref={senderRef}
key={curConversation}
slotConfig={slotConfig}
loading={isRequesting}
onSubmit={(val) => {
if (!val) return;
onRequest({
messages: [{ role: 'user', content: val }],
thinking: {
type: 'disabled',
},
});
listRef.current?.scrollTo({ top: 'bottom' });
setActiveConversation(curConversation);
senderRef.current?.clear?.();
}}
onCancel={() => {
abort();
}}
placeholder={locale.placeholder}
footer={(actionNode) => {
return (
<Flex justify="space-between" align="center">
<Flex gap="small" align="center">
<Sender.Switch
value={deepThink}
onChange={(checked: boolean) => {
setDeepThink(checked);
}}
icon={<OpenAIOutlined />}
>
{locale.deepThink}
</Sender.Switch>
</Flex>
<Flex align="center">{actionNode}</Flex>
</div>
<div className={clsx(styles.chatSender, { [styles.startPage]: messages.length === 0 })}>
{messages.length === 0 && <div className={styles.agentName}>{locale.agentName}</div>}
<Sender
suffix={false}
ref={senderRef}
key={curConversation}
slotConfig={slotConfig}
loading={isRequesting}
onSubmit={(val) => {
if (!val) return;
onRequest({
messages: [{ role: 'user', content: val }],
thinking: {
type: 'disabled',
},
});
listRef.current?.scrollTo({ top: 'bottom' });
setActiveConversation(curConversation);
senderRef.current?.clear?.();
}}
onCancel={() => {
abort();
}}
placeholder={locale.placeholder}
footer={(actionNode) => {
return (
<Flex justify="space-between" align="center">
<Flex gap="small" align="center">
<Sender.Switch
value={deepThink}
onChange={(checked: boolean) => {
setDeepThink(checked);
}}
icon={<OpenAIOutlined />}
>
{locale.deepThink}
</Sender.Switch>
</Flex>
);
}}
autoSize={{ minRows: 3, maxRows: 6 }}
/>
</div>
<Flex align="center">{actionNode}</Flex>
</Flex>
);
}}
autoSize={{ minRows: 3, maxRows: 6 }}
/>
</div>
</div>
</div>
Expand Down
Loading