From 91333ffa6c59a3c2bb5dbb16b77f4b6e2a84b018 Mon Sep 17 00:00:00 2001 From: Albert Yu Date: Wed, 4 Sep 2024 21:23:12 +0800 Subject: [PATCH] Refactor useCollapsibleTrigger with useButton --- .../Accordion/Trigger/AccordionTrigger.tsx | 6 +- .../Trigger/CollapsibleTrigger.tsx | 2 +- .../Trigger/useCollapsibleTrigger.ts | 58 ++++++++++++++----- 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/packages/mui-base/src/Accordion/Trigger/AccordionTrigger.tsx b/packages/mui-base/src/Accordion/Trigger/AccordionTrigger.tsx index e44053457..9ace5192f 100644 --- a/packages/mui-base/src/Accordion/Trigger/AccordionTrigger.tsx +++ b/packages/mui-base/src/Accordion/Trigger/AccordionTrigger.tsx @@ -20,7 +20,7 @@ import { accordionStyleHookMapping } from '../Section/styleHooks'; */ const AccordionTrigger = React.forwardRef(function AccordionTrigger( props: AccordionTrigger.Props, - forwardedRef: React.ForwardedRef, + forwardedRef: React.ForwardedRef, ) { const { disabled: disabledProp, className, render, ...otherProps } = props; @@ -28,9 +28,10 @@ const AccordionTrigger = React.forwardRef(function AccordionTrigger( const { getRootProps } = useCollapsibleTrigger({ contentId, + disabled: disabledProp || contextDisabled, open, + rootRef: forwardedRef, setOpen, - disabled: disabledProp || contextDisabled, }); const { ownerState, triggerId } = useAccordionSectionContext(); @@ -40,7 +41,6 @@ const AccordionTrigger = React.forwardRef(function AccordionTrigger( render: render ?? 'button', ownerState, className, - ref: forwardedRef, extraProps: { ...otherProps, id: triggerId }, customStyleHookMapping: accordionStyleHookMapping, }); diff --git a/packages/mui-base/src/Collapsible/Trigger/CollapsibleTrigger.tsx b/packages/mui-base/src/Collapsible/Trigger/CollapsibleTrigger.tsx index f8c410a1b..063f11f43 100644 --- a/packages/mui-base/src/Collapsible/Trigger/CollapsibleTrigger.tsx +++ b/packages/mui-base/src/Collapsible/Trigger/CollapsibleTrigger.tsx @@ -30,6 +30,7 @@ const CollapsibleTrigger = React.forwardRef(function CollapsibleTrigger( contentId, open, setOpen, + rootRef: forwardedRef, }); const { renderElement } = useComponentRenderer({ @@ -37,7 +38,6 @@ const CollapsibleTrigger = React.forwardRef(function CollapsibleTrigger( render: render ?? 'button', ownerState, className, - ref: forwardedRef, extraProps: otherProps, customStyleHookMapping: collapsibleStyleHookMapping, }); diff --git a/packages/mui-base/src/Collapsible/Trigger/useCollapsibleTrigger.ts b/packages/mui-base/src/Collapsible/Trigger/useCollapsibleTrigger.ts index 28e07b0c4..5af2603db 100644 --- a/packages/mui-base/src/Collapsible/Trigger/useCollapsibleTrigger.ts +++ b/packages/mui-base/src/Collapsible/Trigger/useCollapsibleTrigger.ts @@ -1,24 +1,51 @@ 'use client'; import * as React from 'react'; import { mergeReactProps } from '../../utils/mergeReactProps'; - +import { useForkRef } from '../../utils/useForkRef'; +import { GenericHTMLProps } from '../../utils/types'; +import { useButton } from '../../useButton'; +/** + * + * Demos: + * + * - [Collapsible](https://mui.com/base-ui/react-collapsible/#hooks) + * + * API: + * + * - [useCollapsibleTrigger API](https://mui.com/base-ui/react-collapsible/hooks-api/#use-collapsible-trigger) + */ export function useCollapsibleTrigger( parameters: useCollapsibleTrigger.Parameters, ): useCollapsibleTrigger.ReturnValue { - const { contentId, disabled, open, setOpen } = parameters; + const { contentId, disabled, open, rootRef: externalRef, setOpen } = parameters; + + const { getRootProps: getButtonProps, rootRef: buttonRef } = useButton({ + disabled, + focusableWhenDisabled: true, + type: 'button', + }); + + const handleRef = useForkRef(externalRef, buttonRef); const getRootProps: useCollapsibleTrigger.ReturnValue['getRootProps'] = React.useCallback( - (externalProps = {}) => - mergeReactProps<'button'>(externalProps, { - type: 'button', - 'aria-controls': contentId, - 'aria-expanded': open, - disabled, - onClick() { - setOpen(!open); - }, - }), - [contentId, disabled, open, setOpen], + (externalProps: GenericHTMLProps = {}) => + mergeReactProps( + externalProps, + mergeReactProps( + { + type: 'button', + 'aria-controls': contentId, + 'aria-expanded': open, + disabled, + onClick() { + setOpen(!open); + }, + ref: handleRef, + }, + getButtonProps(), + ), + ), + [contentId, disabled, getButtonProps, handleRef, open, setOpen], ); return { @@ -37,6 +64,7 @@ export namespace useCollapsibleTrigger { * The open state of the Collapsible */ open: boolean; + rootRef?: React.Ref; /** * A state setter that sets the open state of the Collapsible */ @@ -44,8 +72,6 @@ export namespace useCollapsibleTrigger { } export interface ReturnValue { - getRootProps: ( - externalProps?: React.ComponentPropsWithRef<'button'>, - ) => React.ComponentPropsWithRef<'button'>; + getRootProps: (externalProps?: GenericHTMLProps) => GenericHTMLProps; } }