Grapes homepage1.57.0
  • Guide
  • Tokens
  • Components
    Grapes on GithubGrapes on Figma
    Interaction
    • Button
    • IconButton
    • FloatingActionBar
    • Link
    Icons
    • Icon
    • HighlightIcon
    Form
    • AmountInput
    • Autocomplete
    • AutocompleteMultiple
    • AutocompletePlace
    • CheckboxBox
    • CheckboxField
    • DatePicker
    • FormField
    • Input
    • OptionGroup
    • PasswordInput
    • PhoneInput
    • RadioBox
    • RadioField
    • RadioGroup
    • Select
    • SwitchField
    • TextArea
    • TextInput
    • Upload
    • UploadButton
    Feedback
    • Badge
    • Banner
    • Callout
    • EmptyState
    • Modal
    • ModalSlideshow
    • DeprecatedModalSlideshow
    • PageModal
    • Skeleton
    • Tag
    • Toast
    • Tooltip
    Data display
    • Accordion
    • Avatar
    • Box
    • Calendar
    • CalendarRange
    • CollapsibleList
    • FileCard
    • InfoTip
    • ListBox
    • ListView
    • Panel
    • SidePanel
    • DeprecatedPreview
    • Table
    • Timeline
    • useDateFormatter
    Navigation
    • DropdownItem
    • DropdownMenu
    • Navigation
    • NavigationItem
    • Popover
    • Tabs

    CollapsibleList

    View source code
    • Usage
    • Props

    Import

    • CollapsibleList: The collapsible list component.
    • CollapsibleListItem: A helper component designed to represent an item inside a collapsible list.

    Basic usage

    Content Overflow

    By definition, a collapsible list is meant to hide elements when collapsed, which requires that no elements overflow the list limits.

    It means that Popover, Select and DropdownMenu are not compatible with the CollapsibleList component, as they can't overflow the list limits. It is recommended to avoid using these components within a CollapsibleList to ensure proper functionality.

    const Demo = () => {
      const [activeListItem, setActiveListItem] = useState<number | null>(null);
      const [selectedListItems, setSelectedListItems] = useState<number[]>([]);
    
      function onSelect(id: number) {
        if (selectedListItems.includes(id)) {
          setSelectedListItems(selectedListItems.filter((item) => item !== id));
        } else {
          setSelectedListItems([...selectedListItems, id]);
        }
      }
    
      return (
        <div className="w-[360px]">
          <CollapsibleList
            renderHeader={(toggle, isCollapsed) => (
              <CollapsibleListItem
                asHeader
                isCollapsed={isCollapsed}
                onClick={toggle}
                isSelected={selectedListItems.length === 3}
                isIndeterminate={
                  selectedListItems.length > 0 && selectedListItems.length < 3
                }
                onSelect={() => {
                  if (selectedListItems.length < 3) {
                    setSelectedListItems([0, 1, 2]);
                  } else {
                    setSelectedListItems([]);
                  }
                }}
              >
                Header
              </CollapsibleListItem>
            )}
          >
            <CollapsibleListItem
              isActive={activeListItem === 0}
              onClick={() => setActiveListItem(0)}
              isSelected={selectedListItems.includes(0)}
              onSelect={() => onSelect(0)}
            >
              Item 1
            </CollapsibleListItem>
            <CollapsibleListItem
              isActive={activeListItem === 1}
              onClick={() => setActiveListItem(1)}
              isSelected={selectedListItems.includes(1)}
              onSelect={() => onSelect(1)}
            >
              Item 2
            </CollapsibleListItem>
            <CollapsibleListItem
              isActive={activeListItem === 2}
              onClick={() => setActiveListItem(2)}
              isSelected={selectedListItems.includes(2)}
              onSelect={() => onSelect(2)}
            >
              Item 3
            </CollapsibleListItem>
          </CollapsibleList>
        </div>
      );
    };
    

    Expanded by default

    The isInitialCollapsed prop allows you to specify whether the CollapsibleList should be initially collapsed (default) or expanded. Pass isInitialCollapsed={false} to expand the CollapsibleList at the first render.

    <CollapsibleList isInitialCollapsed={false} {...otherProps}>
      ...
    </CollapsibleList>
    

    Footer

    The footer prop allows you to add a footer to the CollapsibleList.

    <CollapsibleList
      footer={
        withFooter && (
          <Button
            text="Load more"
            variant="secondaryNeutral"
            onClick={() => console.log("Load more")}
          />
        )
      }
      {...otherProps}
    >
      ...
    </CollapsibleList>
    

    Variant

    CollapsibleListItems can have an alert variant.

    <CollapsibleList {...otherProps}>
      <CollapsibleListItem>Item 1</CollapsibleListItem>
      <CollapsibleListItem variant="alert">Item 2</CollapsibleListItem>
      <CollapsibleListItem>Item 3</CollapsibleListItem>
    </CollapsibleList>