
Refine v5 Mantine 教程SaveButton 组件——表单保存动作的完整实现与定制指南【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refineSaveButton是 Refine v5 中专门用于表单保存动作的按钮组件基于 MantineButton构建是 Edit / Create 页面表单提交流程的核心交互元素。本文以 documentation/docs/ui-integrations/mantine/components/buttons/save-button/index.md 为主体深入讲解其用法、hideText属性并结合仓库源码剖析其底层实现与测试验证。SaveButton 是什么SaveButton是refinedev/mantine包导出的按钮组件它在 MantineButton返回的saveButtonProps会为按钮附加提交、校验、加载态等行为。从源码实现看SaveButton 组件 的核心逻辑非常简洁// packages/mantine/src/components/buttons/save/index.tsx export const SaveButton: React.FCSaveButtonProps ({ hideText false, svgIconProps, children, ...rest }) { const { label } useSaveButton(); const { variant, styles, ...commonProps } rest; return hideText ? ( ActionIcon ... IconDeviceFloppy size{18} {...svgIconProps} / /ActionIcon ) : ( Button variantfilled leftIcon{IconDeviceFloppy size{18} {...svgIconProps} /} ... {children ?? label} /Button ); };几个值得注意的设计点默认渲染为 MantineButton使用filled变体左侧自带一个软盘图标IconDeviceFloppy按钮文字优先取children未传时回退到useSaveButton()返回的labellabel并非硬编码字符串而是通过useActionableButtonHook 从 i18n 翻译函数获取key 为buttons.savefallback 为humanize(save)即 Save详见 actionable-button/index.tsx 与 hooks/button/index.tsx。这意味着 SaveButton 天然支持多语言环境只要在 i18n Provider 中配置buttons.save的翻译按钮文字就会自动本地化。在 Edit 页面中使用 SaveButtonSaveButton 最常见的用法是与useForm配合出现在编辑页面的表单提交场景。原文档给出了完整示例核心思路是把useForm返回的saveButtonProps透传给Edit组件的同名属性由Edit内部的页脚自动渲染 SaveButtonimport { Edit, useForm, useSelect } from refinedev/mantine; import { Select, TextInput } from mantine/core; const PostEdit: React.FC () { const { saveButtonProps, getInputProps, refineCore: { query }, } useFormIPost({ initialValues: { title: , status: , category: { id: , }, }, validate: { title: (value) (value.length 2 ? Too short title : null), status: (value) (value.length 0 ? Status is required : null), category: { id: (value) (value.length 0 ? Category is required : null), }, }, }); const postData query?.data?.data; const { selectProps } useSelectICategory({ resource: categories, defaultValue: postData?.category.id, }); return ( Edit saveButtonProps{saveButtonProps} form TextInput mt{8} labelTitle placeholderTitle {...getInputProps(title)} / Select mt{8} labelStatus placeholderPick one {...getInputProps(status)} data{[ { label: Published, value: published }, { label: Draft, value: draft }, { label: Rejected, value: rejected }, ]} / Select mt{8} labelCategory placeholderPick one {...getInputProps(category.id)} {...selectProps} / /form /Edit ); }; interface ICategory { id: number; title: string; } interface IPost { id: number; title: string; status: published | draft | rejected; category: { id: number }; }saveButtonProps 里到底装了什么saveButtonProps之所以能把保存动作接到表单上是因为 Edit 组件 在内部对传入的 props 做了加工// packages/mantine/src/components/crud/edit/index.tsx const saveButtonProps: SaveButtonProps { ...(isLoading ? { disabled: true } : {}), ...saveButtonPropsFromProps, };然后将其渲染在默认页脚按钮区域const defaultFooterButtons ( {isDeleteButtonVisible DeleteButton {...deleteButtonProps} /} SaveButton {...saveButtonProps} / / );也就是说在isLoading为true例如查询数据或提交中时保存按钮会自动进入disabled状态避免用户重复提交。Create 页面 create/index.tsx 采用了完全相同的模式。这一点对表单交互体验至关重要也是saveButtonProps相比手动编写button typesubmit的核心价值所在。属性详解hideTexthideText用于控制按钮文字是否显示。当设为true时按钮只保留图标软盘适合工具栏、紧凑布局或已附带文字说明的场景import { SaveButton } from refinedev/mantine; const MySaveComponent () { return SaveButton hideText /; };从源码可以看到hideText的完整渲染逻辑save/index.tsxhideText为true时渲染为 MantineActionIcon图标按钮默认variantfilled、colorprimary如果调用方传了variant则通过mapButtonVariantToActionIconVariant做一次映射definitions/button/index.ts该映射仅将white变体转换为default其余原样透传hideText为false默认时渲染为常规Button文字为children ?? label。两种形态都会带上data-testidRefineButtonTestIds.SaveButton与classNameRefineButtonClassNames.SaveButton便于测试与全局样式定制。API 一览SaveButton的 Props 类型定义在 ui-types/src/types/button.tsxexport type RefineSaveButtonProps TComponentProps extends {} Recordstring, unknown, TExtraProps extends {} {}, RefineButtonCommonProps RefineButtonLinkingProps TComponentProps TExtraProps {};展开后常用属性包括属性类型说明hideTextboolean是否隐藏文字只显示图标默认falsechildrenReactNode自定义按钮文字未传时使用默认 labelSaveonClickPointerEventHandler点击回调来自RefineButtonLinkingPropsvariantButtonVariantMantine 按钮变体透传给底层 ButtonsvgIconPropsIconProps透传给软盘图标的属性Mantine 包特有扩展在 mantine 包的类型定义 中SaveButtonProps还额外组合了svgIconProps这类 Mantine 特有的扩展属性用于定制图标尺寸、颜色等。由于TComponentProps默认继承 MantineButton的全部ButtonPropssize、color、radius、loading等原生属性均可直接透传。用 Refine CLI swizzle 定制原文档特别提到可以用Refine CLI对组件执行 swizzle 操作将其弹出到你的项目源码中再进行深度定制。swizzle 后组件会成为项目内的普通组件你可以直接修改其 JSX、样式或逻辑而不受包更新影响。相关 CLI 说明见 packages/cli 的文档与实现。源码验证测试覆盖了什么refinedev/ui-tests提供了一套跨 UI 库通用的 SaveButton 测试Mantine 实现通过一行代码接入save/index.spec.tsximport { buttonSaveTests } from refinedev/ui-tests; import { SaveButton } from ./; describe(Save Button, () { buttonSaveTests.bind(this)(SaveButton); });通用测试用例定义在 ui-tests/src/tests/buttons/save.tsx覆盖了五个核心行为基本渲染SaveButton /能正常挂载test-id渲染结果中存在RefineButtonTestIds.SaveButtonchildren 渲染传入SaveButtonrefine/SaveButton时页面文本中出现 refinehideTextSaveButton hideText /时页面文本中不再出现 Save只显示图标点击回调点击按钮触发onClick且只触发一次。同时useActionableButton本身也有单测actionable-button/index.spec.tsx验证了save/export/import三种类型分别返回 Save / Export / Import 的默认标签。这些测试保证了 SaveButton 在四个主流 UI 库Ant Design、MUI、Mantine、Chakra UI之间的行为一致性。小结在 Refine v5 中SaveButton 是一个薄封装 深度集成的组件呈现层由 MantineButton承载支持hideText纯图标模式与svgIconProps图标定制行为层由useForm的saveButtonProps注入通过 Edit / Create 页脚自动获得提交、校验、加载态禁用等能力文案层由useActionableButton提供默认 Save可经由buttons.save翻译 key 实现 i18n 本地化可定制性由 Refine CLI swizzle 保障弹出源码后可按需改造。掌握 SaveButton 的用法与内部机制是构建专业、可维护的 Mantine 后台表单界面的基础一步。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考