ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Refine 框架 Chakra UI ListButton 组件完全指南:属性、源码原理与实战用法

Refine 框架 Chakra UI ListButton 组件完全指南:属性、源码原理与实战用法 Refine 框架 Chakra UI ListButton 组件完全指南属性、源码原理与实战用法【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine导读ListButton是 Refine 框架为 Chakra UI 用户提供的内置导航按钮用于一键跳转到某个 resource 的列表页list page路由。本指南以 Refine v3 版本文档documentation/versioned_docs/version-3.xx.xx/api-reference/chakra-ui/components/buttons/list.md为骨架结合当前仓库中 Chakra UI 适配层与核心 hooks 的源码实现讲解该组件的使用场景、全部属性resourceNameOrRouteName、hideText、accessControl等、底层跳转原理以及它与Show等 CRUD 组件的默认集成方式。读完本文你将能在自己的 Refine Chakra UI 应用中熟练使用并定制列表跳转按钮。组件概览基于 Chakra Button 的列表导航入口ListButton直接构建在 Chakra UI 的Button的list方法完成跳转。它最适合用于需要返回列表页的场景例如 Show 页面、Edit 页面的头部操作区让用户可以从详情/编辑视图快速回到该 resource 的列表路由。当前仓库中Chakra UI 的ListButton实现在 packages/chakra-ui/src/components/buttons/list/index.tsx并通过 packages/chakra-ui/src/components/buttons/index.tsx 统一导出。其组件声明如下import { useListButton } from refinedev/core; import { IconButton, Button } from chakra-ui/react; import { IconList } from tabler/icons-react; export const ListButton: React.FCListButtonProps ({ resource: resourceNameFromProps, hideText false, accessControl, svgIconProps, meta, children, onClick, ...rest }) { const { to, label, title, hidden, disabled, LinkComponent } useListButton({ resource: resourceNameFromProps, accessControl, meta, }); // ... };从实现可以看到几个关键点按钮文案与跳转目标都不是写死的而是由useListButtonhook 根据 resource 定义计算得出默认渲染为variantoutline的Button左侧带IconList图标来自tabler/icons-react当hideText为true时渲染为仅图标的IconButton整个按钮包在LinkComponent中最终渲染为可导航的链接式按钮组件带有统一的data-testid与className分别来自RefineButtonTestIds.ListButton与RefineButtonClassNames.ListButton便于端到端测试与样式定制。基本用法在 Show 页面头部放置列表按钮文档给出的典型使用场景是把ListButton作为Show组件的headerButtons让详情页头部出现返回列表入口import { useShow } from pankod/refine-core; import { Show, Heading, Text, Spacer, MarkdownField, ListButton, } from pankod/refine-chakra-ui; const PostShow: React.FCIResourceComponentsProps () { const { queryResult } useShowIPost(); const { data, isLoading } queryResult; const record data?.data; return ( Show headerButtons{ListButton /} isLoading{isLoading} Heading ash5 sizesm Id /Heading Text mt{2}{record?.id}/Text Heading ash5 sizesm mt{4} Title /Heading Text mt{2}{record?.title}/Text Heading ash5 sizesm mt{4} Content /Heading Spacer mt{2} / MarkdownField value{record?.content} / /Show ); };配合 resource 定义const App () { return ( Refine notificationProvider{RefineChakra.notificationProvider()} resources{[ { name: posts, show: PostShow, list: () ( RefineChakra.VStack alignItemsflex-start RefineChakra.TextThis page is empty./RefineChakra.Text ShowButton colorSchemeblack recordItemId123 Show Item 123 /ShowButton /RefineChakra.VStack ), }, ]} / ); };按钮文案由 resource 自动生成文档特别强调按钮文本由 refine 根据 resource 对象的name属性自动定义无需手动书写。这意味着当 resource 名为posts时按钮默认显示为复数形式Posts该逻辑在useNavigationButton中通过useTranslate与useUserFriendlyName协作完成详见下文底层原理一节。你也可以通过children显式覆盖文案。属性详解PropertiesresourceNameOrRouteName跳转端点resourceNameOrRouteName/list由resourceNameOrRouteName属性决定。默认情况下ListButton使用 resource 对象的name属性作为点击后的跳转端点。当需要跳转到当前路由之外的另一个 resource 列表时显式传入该属性即可import { ListButton } from pankod/refine-chakra-ui; const MyListComponent () { return ( ListButton colorSchemeblack resourceNameOrRouteNamecategories / ); };配合如下 resource 配置点击按钮将触发useNavigation的list方法并重定向到/categoriesconst App () { return ( Refine resources{[ { name: posts, list: MyListComponent }, { name: categories, list: ListPage }, ]} / ); };说明在仓库当前版本的源码中这一能力由resource属性承担。例如 packages/chakra-ui/src/components/buttons/list/index.tsx 将resource透传给useListButtonpackages/ui-types/src/types/button.tsx 中RefineButtonResourceProps的注释也说明resource用于 API 数据交互的资源名identifier可替代name默认值从路由推断 resource 名。两者语义一致只是 v3 文档命名与此后版本存在 API 命名演进。hideText用于控制按钮文本的显示与隐藏。当设为true时按钮只显示图标列表图标适合空间紧凑的工具栏场景import { ListButton } from pankod/refine-chakra-ui; const MyListComponent () { return ListButton colorSchemeblack hideText /; };在源码层面hideText默认值为false见 list/index.tsx。当其为true时组件切换为IconButton渲染并通过aria-label{label}保留无障碍语义测试用例 packages/ui-tests/src/tests/buttons/list.tsx 专门验证了只显示图标、不渲染文本Posts 不出现在文档中的行为。accessControl该属性用于控制按钮的访问权限检查行为仅在向Refine/提供了accessControlProvider时生效。它包含两个子属性enabled是否启用访问控制检查源码类型定义中的默认值为{ enabled: true }见 packages/ui-types/src/types/button.tsxhideIfUnauthorized当用户没有访问该 resource 的权限时是否直接隐藏按钮。典型用法如下import { ListButton } from pankod/refine-chakra-ui; export const MyListComponent () { return ( ListButton accessControl{{ enabled: true, hideIfUnauthorized: true }} / ); };关于accessControl的行为可以从统一测试套件 packages/ui-tests/src/tests/buttons/list.tsx 中得到完整验证默认行为无权限按钮渲染为禁用态并带上can返回的reason作为title如 Access Denied全局hideIfUnauthorized: true且无权限按钮完全不渲染显式accessControl{{ enabled: false }}即使全局启用了访问控制按钮也保持可用通过 prop 单独开启hideIfUnauthorized可在全局关闭时针对单个按钮开启隐藏策略访问控制生效时disabledprop 依然被尊重测试用例 should respect the disabled prop even with access control enabled。这些用例清晰展示了按钮级访问控制与全局配置accessControlProvider.options.buttons之间的优先级与叠加关系。其他可用属性结合 packages/chakra-ui/src/components/buttons/types.ts 与 packages/ui-types/src/types/button.tsxListButtonProps由以下基础类型组合而成RefineButtonCommonPropshideText、children自定义按钮文案RefineButtonResourcePropsresource、accessControlRefineButtonLinkingPropsonClick点击事件处理器注意源码中自定义onClick会preventDefault并取代默认跳转RefineButtonURLPropsmeta用于构造相关 action 的 URL 与路径Chakra UI 的ButtonProps如colorScheme、size、variant、disabled、hidden等经...rest透传Chakra UI 特有的svgIconProps自定义IconList图标的 props。其中hidden与disabled在组件内被单独合并处理见 list/index.tsxhidden为真时组件直接返回null不渲染disabled为真时点击事件被preventDefault拦截。底层原理从 ListButton 到 useNavigation.list文档指出组件在底层使用useNavigation的list方法结合仓库源码可以把整条调用链完整还原UI 组件层ListButton调用useListButtonhookpackages/chakra-ui/src/components/buttons/list/index.tsx核心 hook 层useListButton是通用导航按钮 hook 的list动作特化——见 packages/core/src/hooks/button/index.tsxexport const useListButton ( props: PrettifyOmitNavigationButtonProps, action | id, ) useNavigationButton({ ...props, action: list });导航计算层useNavigationButtonpackages/core/src/hooks/button/navigation-button/index.tsx针对list动作调用navigation.listUrl(resource, meta)生成目标路由const to React.useMemo(() { if (!resource) return ; switch (props.action) { case create: case list: return navigation${props.action}Url; default: if (!id) return ; return navigation${props.action}Url; } }, [resource, id, props.meta, navigation[${props.action}Url]]);路由解析层listUrlpackages/core/src/hooks/navigation/index.ts从当前 resource 的 action 路由中查找listaction 对应的 route再通过go组合出最终路径若当前 resource 未定义 list 路由则返回空字符串。此外按钮文案label的生成逻辑也在该 hook 中navigation-button/index.tsx对list动作它优先翻译{identifier}.titles.list键回退到useUserFriendlyName生成的资源复数名这就是按钮文本由 resource 自动定义的源码级出处。按钮的禁用/隐藏/权限状态则由useButtonCanAccess统一计算。与 CRUD 组件的默认集成Show 页面开箱即用值得强调的是即使不手动传入headerButtonsShow组件默认也会渲染一个ListButton。查看 packages/chakra-ui/src/components/crud/show/index.tsx 可以发现const listButtonProps: ListButtonProps | undefined hasList ? { ...(isLoading ? { disabled: true } : {}), resource: identifier, } : undefined; const defaultHeaderButtons ( {listButtonProps ListButton {...listButtonProps} /} {isEditButtonVisible EditButton colorSchemebrand {...editButtonProps} /} {isDeleteButtonVisible DeleteButton {...deleteButtonProps} /} RefreshButton {...refreshButtonProps} / / );这意味着只要 resource 定义了list页面Show 详情页头部就会自动出现列表按钮数据加载期间按钮自动禁用你也可以通过headerButtonsprop 传入自定义按钮数组来整体替换这一组默认头部按钮。这解释了文档示例中为什么Show里直接传一个ListButton /就够了。常见问题与使用建议跳转目标不对确认 resource 是否定义了list页面resourceNameOrRouteName当前源码中为resource指向的必须是已注册的 resource 名称或路由名。想改按钮文案直接传入children覆盖自动生成的文本即可默认文本来自{resource}.titles.list的 i18n 翻译或资源名的复数形式。图标按钮无障碍使用hideText时组件自动以label作为aria-label无需额外处理。权限控制需要隐藏而非禁用时使用accessControl{{ hideIfUnauthorized: true }}注意它依赖全局accessControlProvider的注入。完全自定义文档提示可通过 refine CLI 的 swizzle 功能将此组件解包到你的项目中再深度定制这一能力对应文档 frontmatter 中的swizzle: true标记。小结ListButton虽小却完整体现了 Refine 的组件设计哲学UI 适配层Chakra UI只负责渲染导航计算、文案生成与权限判断全部下沉到核心层 hooks。通过本文的属性和源码分析可以看到从 v3 文档中的resourceNameOrRouteName到当前源码的resource其语义一脉相承而hideText、accessControl、meta等能力在 packages/ui-tests/src/tests/buttons/list.tsx 的统一测试中均有覆盖可以作为你使用或定制该组件时的行为基准。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表