2020-06-05 10:00:19 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
|
|
|
import { useState } from '@wordpress/element';
|
2024-05-31 03:49:36 +00:00
|
|
|
import clsx from 'clsx';
|
2022-02-01 16:54:38 +00:00
|
|
|
import { Icon, chevronUp, chevronDown } from '@wordpress/icons';
|
2023-03-02 14:26:00 +00:00
|
|
|
import type { ReactNode, ReactElement } from 'react';
|
2024-09-16 13:03:20 +00:00
|
|
|
import { Button } from '@ariakit/react';
|
|
|
|
import deprecated from '@wordpress/deprecated';
|
2020-06-05 10:00:19 +00:00
|
|
|
/**
|
|
|
|
* Internal dependencies
|
|
|
|
*/
|
|
|
|
import './style.scss';
|
|
|
|
|
2023-11-20 15:26:21 +00:00
|
|
|
export interface PanelProps {
|
|
|
|
children: ReactNode;
|
|
|
|
className?: string | undefined;
|
2021-03-05 14:03:48 +00:00
|
|
|
initialOpen?: boolean;
|
|
|
|
hasBorder?: boolean;
|
2023-11-20 15:26:21 +00:00
|
|
|
title: ReactNode;
|
2021-03-05 14:03:48 +00:00
|
|
|
titleTag?: keyof JSX.IntrinsicElements;
|
2024-04-25 05:03:31 +00:00
|
|
|
state?: [ boolean, React.Dispatch< React.SetStateAction< boolean > > ];
|
2021-03-05 14:03:48 +00:00
|
|
|
}
|
|
|
|
|
2020-06-05 10:00:19 +00:00
|
|
|
const Panel = ( {
|
|
|
|
children,
|
|
|
|
className,
|
|
|
|
initialOpen = false,
|
2020-06-12 12:07:02 +00:00
|
|
|
hasBorder = false,
|
2020-06-05 10:00:19 +00:00
|
|
|
title,
|
2024-09-16 13:03:20 +00:00
|
|
|
/**
|
|
|
|
* @deprecated The `titleTag` prop is deprecated and will be removed in a future version.
|
|
|
|
* Use the `title` prop to pass a custom React element instead.
|
|
|
|
*/
|
|
|
|
titleTag,
|
2024-04-25 05:03:31 +00:00
|
|
|
state,
|
2021-03-05 14:03:48 +00:00
|
|
|
}: PanelProps ): ReactElement => {
|
2024-04-25 05:03:31 +00:00
|
|
|
let [ isOpen, setIsOpen ] = useState< boolean >( initialOpen );
|
|
|
|
// If state is managed externally, we override the internal state.
|
|
|
|
if ( Array.isArray( state ) && state.length === 2 ) {
|
|
|
|
[ isOpen, setIsOpen ] = state;
|
|
|
|
}
|
2020-06-05 10:00:19 +00:00
|
|
|
|
2024-09-16 13:03:20 +00:00
|
|
|
if ( titleTag ) {
|
|
|
|
deprecated( "Panel component's titleTag prop", {
|
|
|
|
since: '9.4.0',
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2020-06-05 10:00:19 +00:00
|
|
|
return (
|
|
|
|
<div
|
2024-05-31 03:49:36 +00:00
|
|
|
className={ clsx( className, 'wc-block-components-panel', {
|
2020-06-12 12:07:02 +00:00
|
|
|
'has-border': hasBorder,
|
|
|
|
} ) }
|
2020-06-05 10:00:19 +00:00
|
|
|
>
|
2024-09-16 13:03:20 +00:00
|
|
|
<Button
|
|
|
|
render={ <div /> }
|
|
|
|
aria-expanded={ isOpen }
|
|
|
|
className="wc-block-components-panel__button"
|
|
|
|
onClick={ () => setIsOpen( ! isOpen ) }
|
|
|
|
>
|
|
|
|
<Icon
|
|
|
|
aria-hidden="true"
|
|
|
|
className="wc-block-components-panel__button-icon"
|
|
|
|
icon={ isOpen ? chevronUp : chevronDown }
|
|
|
|
/>
|
|
|
|
{ title }
|
|
|
|
</Button>
|
2021-08-13 13:42:09 +00:00
|
|
|
{ isOpen && (
|
|
|
|
<div className="wc-block-components-panel__content">
|
|
|
|
{ children }
|
|
|
|
</div>
|
|
|
|
) }
|
2020-06-05 10:00:19 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default Panel;
|