-
-
Notifications
You must be signed in to change notification settings - Fork 50k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Modal footer support custom render function #44318
Conversation
Run & review this pull request in StackBlitz Codeflow. |
641db8d
to
0747936
Compare
components/modal/index.zh-CN.md
Outdated
@@ -54,7 +55,7 @@ demo: | |||
| confirmLoading | 确定按钮 loading | boolean | false | | | |||
| destroyOnClose | 关闭时销毁 Modal 里的子元素 | boolean | false | | | |||
| focusTriggerAfterClose | 对话框关闭后是否需要聚焦触发元素 | boolean | true | 4.9.0 | | |||
| footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | ReactNode | (确定取消按钮) | | | |||
| footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | (originNode: React.ReactNode, extra: { ConfirmBtn: FC; CancelBtn: FC }) => React.ReactNode \| React.ReactNode | (确定取消按钮) | 5.9.0 | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
感觉需要有个 TS 定义放在 Popover 的交互比较好,这里面越写越长了。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
可以,我加一个类型吧,然后链接过去
size-limit report 📦
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
体积怎么多了这么多。 |
代码层面感觉加的不多,是第三方依赖更新? |
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## feature #44318 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 663 668 +5
Lines 11309 11325 +16
Branches 3051 3062 +11
=========================================
+ Hits 11309 11325 +16
☔ View full report in Codecov by Sentry. |
不是的,这个体积对比就只对比代码本身的变化。看上去拆了很多新组件文件出来,看下是否有必要。 |
因为这个 API 需要把原来写在一起的 |
75f96b2
to
6adc8c6
Compare
close, | ||
onCancel, | ||
onConfirm, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这两排属性声明了很多次,蛮占体积,是否是有必要的?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
我尝试去掉吧,再优化一下
rootPrefixCls, | ||
close, | ||
onCancel, | ||
onConfirm, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里也有一排
24f3ea8
to
bded5e8
Compare
components/modal/Modal.tsx
Outdated
footer === undefined ? <Footer {...props} onOk={handleOk} onCancel={handleCancel} /> : footer; | ||
footer === undefined || typeof footer === 'function' ? ( | ||
<Footer {...props} onOk={handleOk} onCancel={handleCancel} /> | ||
) : ( | ||
footer | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
同上, 可以考虑抽象为一个函数来判断, 三元运算有点多了
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
逻辑感觉不是很复杂吧,一个三目感觉可以搞定?
components/modal/ConfirmDialog.tsx
Outdated
{footer === undefined ? ( | ||
<div className={`${confirmPrefixCls}-btns`}> | ||
{cancelButton} | ||
<ActionButton | ||
isSilent={isSilent} | ||
type={okType} | ||
actionFn={onOk} | ||
close={(...args: any[]) => { | ||
close?.(...args); | ||
onConfirm?.(true); | ||
}} | ||
autoFocus={autoFocusButton === 'ok'} | ||
buttonProps={okButtonProps} | ||
prefixCls={`${rootPrefixCls}-btn`} | ||
> | ||
{okText || (mergedOkCancel ? mergedLocale?.okText : mergedLocale?.justOkText)} | ||
</ActionButton> | ||
</div> | ||
|
||
{footer === undefined || typeof footer === 'function' ? ( | ||
<ConfirmOkBtnProvider value={confirmBtnCtxValueMemo}> | ||
<ConfirmCancelBtnContextProvider value={cancelBtnCtxValueMemo}> | ||
<div className={`${confirmPrefixCls}-btns`}> | ||
{footer === undefined | ||
? footerOriginNode | ||
: footer?.(footerOriginNode, { | ||
ConfirmBtn, | ||
CancelBtn, | ||
})} | ||
</div> | ||
</ConfirmCancelBtnContextProvider> | ||
</ConfirmOkBtnProvider> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这段代码感觉不是那么好阅读
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
确实,可能嵌套多了,看起来代码不是很直观,但这也是我目前能想到最简洁的了,有优化建议不?
components/modal/index.en-US.md
Outdated
## footerRenderParams | ||
|
||
<!-- prettier-ignore --> | ||
| Property | Description | Type | Default | | ||
| --- | --- | --- | --- | | ||
| originNode | default node | React.ReactNode | - | | ||
| extra | extended options | { ConfirmBtn: FC; CancelBtn: FC } | - | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
感觉这里可以直接用 tsx + interface , 比如:(伪代码)
type FooterBuiltinProps = {
ConfirmBtn: React.ReactNode;
CancelBtn: React.ReactNode;
}
type RenderFooter = (originNode: FooterProps, extra: FooterBuiltinProps) => React.ReactNode;
export type FooterProps = React.ReactNode | RenderFooter;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
文档里好像很难显示ts定义
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
那就先保持你的写法~
components/modal/index.zh-CN.md
Outdated
## footerRenderParams | ||
|
||
<!-- prettier-ignore --> | ||
| 参数 | 说明 | 类型 | 默认值 | | ||
| --- | --- | --- | --- | | ||
| originNode | 默认节点 | React.ReactNode | - | | ||
| extra | 扩展选项 | { ConfirmBtn: FC; CancelBtn: FC } | - | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
同上👆🏻
<NormalCancelBtn /> | ||
<NormalOkBtn /> | ||
</> | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这段代码上面出现过一次?和 components/modal/ConfirmDialog.tsx 里的改动基本一样。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
大体逻辑差不多,正常的 Modal
和 Modal.confirm
两边按钮逻辑不太一样,所以又拆了两个按钮出来
components/modal/shared.tsx
Outdated
|
||
const confirmBtnCtxValueMemo = React.useMemo( | ||
() => confirmBtnCtxValue, | ||
[...Object.values(confirmBtnCtxValue)], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这样写行不行呢?(其实我也不太熟悉 23333~)
[...Object.values(confirmBtnCtxValue)], | |
Object.values(confirmBtnCtxValue), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
感觉可以,看起来不需要解构
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
你先本地试试, confirmBtnCtxValue如果是 undefined values 是不是会报错
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这是自己定义的,不会是 undefined
components/modal/shared.tsx
Outdated
); | ||
const cancelBtnCtxValueMemo = React.useMemo( | ||
() => cancelBtnCtxValue, | ||
[...Object.values(cancelBtnCtxValue)], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[...Object.values(cancelBtnCtxValue)], | |
Object.values(cancelBtnCtxValue), |
components/modal/index.en-US.md
Outdated
## footerRenderParams | ||
|
||
<!-- prettier-ignore --> | ||
| Property | Description | Type | Default | | ||
| --- | --- | --- | --- | | ||
| originNode | default node | React.ReactNode | - | | ||
| extra | extended options | { ConfirmBtn: FC; CancelBtn: FC } | - | | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
那就先保持你的写法~
c39e959
to
01ff711
Compare
components/modal/context.ts
Outdated
export const NormalCancelBtnContext = React.createContext<NormalCancelBtnProps>( | ||
{} as NormalCancelBtnProps, | ||
); | ||
export const NormalOkBtnContext = React.createContext<NormalOkBtnProps>({} as NormalOkBtnProps); | ||
export const ConfirmCancelBtnContext = React.createContext<ConfirmCancelBtnProps>( | ||
{} as ConfirmCancelBtnProps, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里能不能只用一个 context,本身都是 Modal 的内部属性
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
应该可以收敛成一个,我一会优化一下
f5dbd4c
to
9db8451
Compare
@@ -42,23 +45,46 @@ export const Footer: React.FC< | |||
onCancel, | |||
okButtonProps, | |||
cancelButtonProps, | |||
footer, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
感觉不应该把 footer 放到 Footer 组件里处理,逻辑应该和 node 一样是整体替换掉的
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
逻辑应该保持一致,要么都在里面处理,要么都在外面处理
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
那我都收到里面去统一处理
077ab8d
to
4572e9f
Compare
多了更多了,加这个功能多了 400B .. |
要拆组件出来好像也确实避免不了...😅 |
</DisabledContextProvider> | ||
) : ( | ||
footer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个是不是也应该放在 provider 里?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
应该不用吧,这个footer应该是用户自己定义的节点,不应该受 provider 的影响
[中文版模板 / Chinese template]
🤔 This is a ...
🔗 Related issue link
close #44297
💡 Background and solution
📝 Changelog
☑️ Self-Check before Merge
🚀 Summary
🤖 Generated by Copilot at 641db8d
This pull request adds a new feature to the
Modal
component and its methods, allowing users to customize the footer rendering function with thefooter
prop. It also refactors the footer buttons into separate components and uses context to pass the props. It updates the documentation, the type definitions, and the test cases accordingly.🔍 Walkthrough
🤖 Generated by Copilot at 641db8d
Modal
andModal.confirm
methods (link, link, link, link, link, link, link, link, link)ConfirmCancelBtn
andConfirmOkBtn
components to replaceActionButton
inConfirmContent
function (link, link, link)NormalCancelBtn
andNormalOkBtn
components to replaceButton
inFooter
function (link, link, link)footer
prop as a function that receives origin node and extra components as arguments (link, link, link, link, link, link, link, link, link, link)Modal
andModal.confirm
methods (link, link)ActionButton
fromConfirmDialog
(link)