reactjstypescriptaccordionstorybookprimereact

PrimeReact AccordionTab Not Rendering When Wrapped in Custom Component


I'm facing an issue where my custom FilterAccordionTab component, which extends PrimeReact's (V8) AccordionTab, is not rendering its content. However, when I directly use PrimeReact's AccordionTab within my custom FilterAccordion component, it works as expected.

Code Details:

FilterAccordion.tsx:

import React from 'react';
import {
  Accordion as PrimeAccordion,
  AccordionTab as PrimeAccordionTab,
} from 'primereact/accordion';
import {
  AccordionProps as PrimeAccordionProps,
  AccordionTabProps as PrimeAccordionTabProps,
} from 'primereact/accordion';

// Extended Accordion props
export interface FilterAccordionProps extends PrimeAccordionProps {
  'data-testid'?: string;
}

// Extended AccordionTab props
export interface FilterAccordionTabProps extends PrimeAccordionTabProps {
  'data-testid'?: string;
}

// FilterAccordion component
export const FilterAccordion: React.FC<FilterAccordionProps> = ({
  children,
  'data-testid': dataTestId,
  ...props
}) => {
  return (
    <PrimeAccordion data-testid={dataTestId} {...props}>
      {children}
    </PrimeAccordion>
  );
};

// FilterAccordionTab component
export const FilterAccordionTab: React.FC<FilterAccordionTabProps> = ({
  children,
  'data-testid': dataTestId,
  ...props
}) => {
  return (
    <PrimeAccordionTab data-testid={dataTestId} {...props}>
      {children}
    </PrimeAccordionTab>
  );
};

Storybook:

import React, { useState } from 'react';
import { Meta, StoryObj } from '@storybook/react';
import {
  FilterAccordion,
  FilterAccordionTab,
  FilterAccordionProps,
} from '..';

type Story = StoryObj<FilterAccordionProps>;

const DefaultTemplate: Story = {
  render: (args) => {
    const [activeIndex, setActiveIndex] = useState<number>(0);

    return (
      <FilterAccordion
        {...args}
        activeIndex={activeIndex}
        onTabChange={(e: any) => setActiveIndex(e.index)}
      >
        <FilterAccordionTab header="Header I">Content I</FilterAccordionTab>
        <FilterAccordionTab header="Header II">Content II</FilterAccordionTab>
        <FilterAccordionTab header="Header III">Content III</FilterAccordionTab>
      </FilterAccordion>
    );
  },
};

export const Default: Story = {
  ...DefaultTemplate,
};

const PlaygroundTemplate: Story = {
  render: (args) => {
    const [activeIndex, setActiveIndex] = useState<number[]>([1, 2]);

    return (
      <FilterAccordion
        {...args}
        activeIndex={activeIndex}
        onTabChange={(e: any) => setActiveIndex([e.index])}
      >
        <FilterAccordionTab header="Header I">Content I</FilterAccordionTab>
        <FilterAccordionTab header="Header II">Content II</FilterAccordionTab>
        <FilterAccordionTab header="Header III">Content III</FilterAccordionTab>
      </FilterAccordion>
    );
  },
};

export const Playground: Story = {
  ...PlaygroundTemplate,
  args: {
    width: '280px',
  },
};

const meta: Meta<FilterAccordionProps> = {
  title: 'Table/Filters/Table Filter Accordion',
  component: FilterAccordion,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: `A 'FilterAccordion' groups a collection of contents in tabs. It consists of one or more FilterAccordionProps elements which are collapsed by default.
        Tab to expand initially can be defined with the activeIndex property.`,
      },
    },
  },
};

export default meta;

Problem:

What I Tried:

  1. Verified that children are being passed correctly in both FilterAccordion and FilterAccordionTab.

  2. Checked the structure and props of both FilterAccordionTab and PrimeAccordionTab.

  3. Added console logs to check the rendering flow (but no logs are shown).

Expected Behavior: FilterAccordionTab should render the content just like PrimeAccordionTab.

Observed Behavior: FilterAccordionTab does not render any content inside FilterAccordion.

Additional Details:

Any insights or suggestions to resolve this would be greatly appreciated. Thank you!


Solution

  • As mentioned in this ticket: https://github.com/primefaces/primereact/issues/2052

    Currently its not possible because AccordionTab's are not components and Accordion is looking specifically for AccordionTabs as its children.