Unable to control a React Aria component

I’m trying to build a custom Accordion component with (Adobe) React Aria. I’m building it on top of the Disclosure and DisclosureGroup components.

import { tv } from "tailwind-variants";
import { motion } from "framer-motion";
import {
  UNSTABLE_Disclosure as DisclosureItem,
  UNSTABLE_DisclosureGroup as Disclosure,
  UNSTABLE_DisclosurePanel as DisclosurePanel,
  DisclosureGroupProps as DisclosureProps,
  DisclosureProps as DisclosureItemProps
} from "react-aria-components";
import ChevronLeft from "@spectrum-icons/workflow/ChevronLeft";
import { useButton, AriaButtonOptions, ButtonAria } from "@react-aria/button";

export const accordion = tv({
  slots: {
    accordion: "p-2",
    item: "",
    header: "flex flex-row"
  },
  variants: {
    colorMode: {
      dark: { accordion: "bg-slate-900 text-white" },
      light: { accordion: "text-slate-800" }
    }
  }
});

export type AccordionProps = Omit<DisclosureProps, "id" | "style" | "isDisabled" | "className"> & Options;

export const Accordion = forwardRef(
  (
    {
      children,
      allowsMultipleExpanded,
      expandedKeys,
      defaultExpandedKeys,
      onExpandedChange,
      className,
      id,
      isVisible,
      borderRadius,
      isLoading,
      error,
      isDisabled
    }: AccordionProps,
    ref: React.LegacyRef<HTMLDivElement>
  ) => {
    return (
      <Disclosure
        ref={ref}
        allowsMultipleExpanded={allowsMultipleExpanded}
        expandedKeys={expandedKeys}
        defaultExpandedKeys={defaultExpandedKeys}
        onExpandedChange={onExpandedChange}
        className={accordion().accordion({ colorMode: "light", class: className })}
        id={id}
        isDisabled={isDisabled}
      >
        {children}
      </Disclosure>
    );
  }
);

export type AccordionItemProps = Omit<DisclosureItemProps, "id" | "style" | "isDisabled" | "className"> & Options;

export const AccordionItem = forwardRef(
  (
    {
      children,
      onExpandedChange,
      className,
      isExpanded,
      defaultExpanded,
      slot,
      id,
      isVisible,
      borderRadius,
      isLoading,
      error,
      isDisabled
    }: AccordionItemProps,
    ref: React.LegacyRef<HTMLDivElement>
  ) => {
    return (
      <DisclosureItem
        ref={ref}
        onExpandedChange={onExpandedChange}
        className={accordion().item({ class: className })}
        isExpanded={isExpanded}
        defaultExpanded={defaultExpanded}
        slot={slot}
        id={id}
        isDisabled={isDisabled}
      >
        {children}
      </DisclosureItem>
    );
  }
);

export type AccordionHeaderProps<T extends ElementType> = {
  children: React.ReactNode;
  iconProps?: AriaButtonOptions<T>;
} & Options;

export const AccordionHeader = forwardRef(
  (
    {
      children,
      iconProps,
      id,
      className,
      isVisible,
      borderRadius,
      isLoading,
      error,
      isDisabled
    }: AccordionHeaderProps<"button">,
    ref
  ) => {
    const { buttonProps } = useButton(iconProps || { elementType: "button" }, ref as RefObject<HTMLButtonElement>);

    // @ts-ignore
    // Type conversion for framer-motion is nessecary so defination is removed
    const ariaButtonProps: Omit<ButtonAria<HTMLAttributes<unknown>>, "defination"> & { defination: undefined } = {
      defination: undefined,
      onAnimationStart: undefined,
      ...buttonProps
    };
    return (
      <div className={accordion().header({ class: className })}>
        <div>{children}</div>
        <motion.button {...ariaButtonProps} disabled={isDisabled} className="ml-auto">
          <ChevronLeft width={25} />
        </motion.button>
      </div>
    );
  }
);

export const AccordionContent = forwardRef(({ children }: { children: React.ReactNode }, ref) => {
  return <DisclosurePanel>{children}</DisclosurePanel>;
});

Please note that I have rearranged the names of the Disclosure from React Aria to better fit my use cases:

  • Disclosure is now DisclosureItem
  • DisclosureGroup is now Disclosure
  • DisclosurePanel is now DisclosureProps

This new accordion component is used like so:

<Accordion>
      <AccordionItem isExpanded>
        <AccordionHeader>
          test
        </AccordionHeader>
        <AccordionContent>
          Hello, World
        </AccordionContent>
      </AccordionItem>
</Accordion>

As you can see I am trying to control one of the AccordionItems however when I preview the component all it is not expanded:

Current

Current

Expected

Expected

I look at the DOM shows that even when isExpanded is true hidden is still applied to the AccordionContent div:

<div class="p-2 text-slate-800" data-rac="">
  <div class="react-aria-Disclosure" data-rac="">
    <div class="flex flex-row">
      <div>test</div>
      <button type="button" class="ml-auto">
        <svg
          viewBox="0 0 36 36"
          class="wBx8DG_spectrum-Icon wBx8DG_spectrum-Icon--sizeM"
          focusable="false"
          aria-hidden="true"
          role="img"
          style="width: 25px"
        >
          <path
            fill-rule="evenodd"
            d="M12,18v0a1.988,1.988,0,0,0,.585,1.409l7.983,7.98a2,2,0,1,0,2.871-2.772l-.049-.049L16.819,18l6.572-6.57a2,2,0,0,0-2.773-2.87l-.049.049-7.983,7.98A1.988,1.988,0,0,0,12,18Z"
          ></path>
        </svg>
      </button>
    </div>
   <!-- Here ⬇️ -->
    <div
      id="react-aria3890111277-:r2:"
      role="group"
      aria-labelledby="react-aria3890111277-:r1:"
      hidden=""
      class="react-aria-DisclosurePanel"
      data-rac=""
    >
      Hello, World
    </div>
  </div>
</div>

Removing hidden shows the element. So my question is how do I do this with RA?