diff --git a/src/components/Panel/Panel.tsx b/src/components/Panel/Panel.tsx index edfe266dc4..8decc8a6a0 100644 --- a/src/components/Panel/Panel.tsx +++ b/src/components/Panel/Panel.tsx @@ -5,7 +5,7 @@ import { useState, useEffect, useRef } from 'preact/hooks'; import cx from 'classnames'; import Template from '../Template/Template'; import { PanelCSSClasses, PanelTemplates } from '../../widgets/panel/panel'; -import { RenderOptions } from '../../types'; +import { RenderOptions, WidgetFactory } from '../../types'; type PanelComponentCSSClasses = Required< Omit< @@ -17,17 +17,19 @@ type PanelComponentCSSClasses = Required< > >; -type PanelProps = { +type PanelProps> = { hidden: boolean; collapsible: boolean; isCollapsed: boolean; data: RenderOptions; cssClasses: PanelComponentCSSClasses; - templates: Required; + templates: Required>; bodyElement: HTMLElement; }; -function Panel(props: PanelProps) { +function Panel>( + props: PanelProps +) { const [isCollapsed, setIsCollapsed] = useState(props.isCollapsed); const [isControlled, setIsControlled] = useState(false); const bodyRef = useRef(null); diff --git a/src/widgets/panel/panel.tsx b/src/widgets/panel/panel.tsx index 8488b421f0..dd638e09d7 100644 --- a/src/widgets/panel/panel.tsx +++ b/src/widgets/panel/panel.tsx @@ -59,16 +59,16 @@ export type PanelCSSClasses = { footer?: string | string[]; }; -export type PanelTemplates = { +export type PanelTemplates> = { /** * Template to use for the header. */ - header?: Template; + header?: Template>; /** * Template to use for the footer. */ - footer?: Template; + footer?: Template>; /** * Template to use for collapse button. @@ -78,11 +78,11 @@ export type PanelTemplates = { export type PanelRenderOptions< TWidget extends WidgetFactory -> = RenderOptions & { - widgetRenderState: ReturnType< - Exclude['getWidgetRenderState'], undefined> - >; -}; +> = RenderOptions & ReturnType['getWidgetRenderState'] extends ( + renderOptions: any +) => infer TRenderState + ? TRenderState + : Record; export type PanelWidgetOptions> = { /** @@ -100,7 +100,7 @@ export type PanelWidgetOptions> = { /** * The templates to use for the widget. */ - templates?: PanelTemplates; + templates?: PanelTemplates; /** * The CSS classes to override. @@ -111,14 +111,14 @@ export type PanelWidgetOptions> = { const withUsage = createDocumentationMessageGenerator({ name: 'panel' }); const suit = component('Panel'); -const renderer = ({ +const renderer = >({ containerNode, bodyContainerNode, cssClasses, templates, }) => ({ options, hidden, collapsible, collapsed }) => { render( - cssClasses={cssClasses} hidden={hidden} collapsible={collapsible} @@ -132,12 +132,12 @@ const renderer = ({ }; export type PanelWidget = >( - params?: PanelWidgetOptions + widgetParams?: PanelWidgetOptions ) => < - TWidgetOptions extends { container: HTMLElement | string; [key: string]: any } + TWidgetParams extends { container: HTMLElement | string; [key: string]: any } >( - widgetFactory: (widgetOptions: TWidgetOptions) => Widget -) => (widgetOptions: TWidgetOptions) => Widget; + widgetFactory: TWidget +) => (widgetOptions: TWidgetParams) => Widget; /** * The panel widget wraps other widgets in a consistent panel design. @@ -222,7 +222,7 @@ const panel: PanelWidget = widgetParams => { `, }; - const renderPanel = renderer({ + const renderPanel = renderer({ containerNode: getContainerNode(container), bodyContainerNode, cssClasses, @@ -259,9 +259,10 @@ const panel: PanelWidget = widgetParams => { const [renderOptions] = args; const options = { + ...(widget.getWidgetRenderState + ? widget.getWidgetRenderState(renderOptions) + : {}), ...renderOptions, - widgetRenderState: (widget.getWidgetRenderState?.(renderOptions) || - {}) as any, }; renderPanel({ diff --git a/stories/panel.stories.ts b/stories/panel.stories.ts index 8f628a3087..156e5f624e 100644 --- a/stories/panel.stories.ts +++ b/stories/panel.stories.ts @@ -151,11 +151,13 @@ storiesOf('Basics/Panel', module) withHits( ({ search, container }) => { const breadcrumbInPanel = panel({ - collapsed({ widgetRenderState }) { - return widgetRenderState.canRefine; + collapsed({ canRefine }) { + return canRefine === false; }, templates: { - header: 'Collapsible panel', + header({ canRefine }) { + return `Breadcrumb that can${canRefine ? '' : "'t "} refine`; + }, footer: 'The panel collapses if it cannot refine. Click "Home". This panel will collapse and you will not see this footer anymore.', },