Collapsible drawer panel that sits above the chat input inside ChatComposer. Pass it to the composer's `drawer` slot to show attachments, context chips, or any supplementary content. When `count` is provided the drawer gains a collapse toggle: collapsed state shows the default Badge and label or caller-provided `collapsedSummary`, while expanded state shows all children.
Preview loads on approachPreview loads on approach
Exact source · chat-composer-drawer-showcase
// Copyright (c) Meta Platforms, Inc. and affiliates.
'use client';
import {ChatComposer, ChatComposerDrawer} from '@astryxdesign/core/Chat';
import {Token} from '@astryxdesign/core/Token';
import {Button} from '@astryxdesign/core/Button';
import {Icon} from '@astryxdesign/core/Icon';
import {Stack} from '@astryxdesign/core/Layout';
import {PaperClipIcon} from '@heroicons/react/24/outline';
import type {CSSProperties} from 'react';
const drawerBorder: CSSProperties = {
border: 'var(--border-width) solid var(--color-border)',
borderTopLeftRadius: 'var(--radius-chat)',
borderTopRightRadius: 'var(--radius-chat)',
};
export default function ChatComposerDrawerShowcase() {
return (
<Stack direction="vertical" gap={4} width={450} maxWidth="100%">
<ChatComposer
onSubmit={() => {}}
drawer={
<ChatComposerDrawer
count={4}
label="Attachments"
style={drawerBorder}>
<Token label="design-spec.pdf" onRemove={() => {}} />
<Token label="api-schema.json" onRemove={() => {}} />
<Token label="screenshot.png" onRemove={() => {}} />
<Token label="meeting-notes.md" onRemove={() => {}} />
</ChatComposerDrawer>
}
headerActions={
<Button
label="Attach"
variant="ghost"
size="sm"
icon={<Icon icon={PaperClipIcon} size="sm" />}
isIconOnly
onClick={() => {}}
/>
}
/>
</Stack>
);
}
Usage
Use ChatComposerDrawer in the ChatComposer drawer slot for supplementary content such as attachments, context chips, or previews. Provide count only when people should be able to collapse that content.
Give label a concrete plural noun such as "Attachments" so the expand and collapse actions have a useful accessible name.
Use controlled isCollapsed with onCollapsedChange when another part of the page owns drawer state; otherwise use defaultIsCollapsed.
Put primary composer actions in the drawer; use ChatComposer footer or send-action slots so those controls remain available when the drawer is collapsed.
Typed props
Prop
Type and behavior
children
ReactNode · required
Content to render inside the drawer: tokens, chips, previews, or any React elements.
count
number
Total item count shown in the collapsed badge. When provided, the drawer gains a collapse/expand toggle.
label
string · default 'Items'
Label shown next to the count in the default collapsed summary and used to name the expand/collapse action.
collapsedSummary
ReactNode
Visual content for the complete Collapsed summary anatomy part. When count enables collapse, this replaces the default neutral Badge and label while the component retains disclosure behavior and accessible naming.
isCollapsed
boolean
Controlled collapsed state. Use with onCollapsedChange for external control.
defaultIsCollapsed
boolean · default false
Initial collapsed state for uncontrolled usage.
onCollapsedChange
(isCollapsed: boolean) => void
Callback fired when the user toggles the drawer.
Anatomy
Root surface · required
The drawer surface that composes above the ChatComposer body.
Disclosure toggle · optional
The keyboard- and pointer-operable collapse control rendered when count is provided.
Collapsed summary · optional
The default count Badge and label, or caller-provided visual content, presented while the drawer is collapsed.
Content area · required
The caller-provided supplementary content; collapsed descendants are unavailable to keyboard and assistive technology.