.pds-chat-panel {
--chat-panel-inset: var(--pds-spacing-l);
background-color: var(--pds-color-surface-default);
color: var(--pds-color-foreground-default);
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
overflow: hidden;
width: 100%;
}
/* Sizes: the PDS Drawer widths. `m` is the default. */
.pds-chat-panel--m {
width: 25rem;
}
.pds-chat-panel--l {
width: 37.5rem;
}
.pds-chat-panel--m,
.pds-chat-panel--l {
max-width: 100%;
}
/* Title row: always inset so the close button never touches the edge. */
.pds-chat-panel__title-row {
align-items: center;
display: flex;
flex-shrink: 0;
gap: var(--pds-spacing-s);
justify-content: flex-end;
padding-block: var(--pds-spacing-m) var(--pds-spacing-s);
padding-inline: var(--chat-panel-inset);
}
.pds-chat-panel__title {
flex: 1;
min-width: 0;
}
.pds-chat-panel__close {
flex-shrink: 0;
}
/* Header and footer: pinned. */
.pds-chat-panel__header,
.pds-chat-panel__footer {
flex-shrink: 0;
}
.pds-chat-panel__header {
padding-block-end: var(--pds-spacing-s);
}
.pds-chat-panel__footer {
padding-block: var(--pds-spacing-s) var(--pds-spacing-m);
}
.pds-chat-panel__header--divider {
border-block-end: var(--pds-border-width-default) solid
var(--pds-color-border-default-secondary);
}
.pds-chat-panel__footer--divider {
border-block-start: var(--pds-border-width-default) solid
var(--pds-color-border-default-secondary);
}
/* Body: holds the scrolling content and, over it, the drop overlay. */
.pds-chat-panel__body {
display: flex;
flex: 1;
flex-direction: column;
min-height: 0;
position: relative;
}
/* Content: the only region that scrolls. */
.pds-chat-panel__content {
flex: 1;
min-height: 0;
overflow-y: auto;
padding-block: var(--pds-spacing-s);
}
/* Content fade: the bottom edge fades out into the footer. The mask only needs
an opaque color. The padding keeps the last line clear at the end. */
.pds-chat-panel__content--fade {
--chat-panel-fade-height: var(--pds-spacing-2xl);
-webkit-mask-image: linear-gradient(
to bottom,
var(--pds-color-foreground-default)
calc(100% - var(--chat-panel-fade-height)),
transparent
);
mask-image: linear-gradient(
to bottom,
var(--pds-color-foreground-default)
calc(100% - var(--chat-panel-fade-height)),
transparent
);
padding-block-end: var(--chat-panel-fade-height);
}
/* The end marker for scroll to latest. */
.pds-chat-panel__end {
height: 0;
}
/* The scroll to latest button floats at the bottom center of the content
area, over the content and outside the faded element. The wrapper ignores
the pointer so only the button takes clicks. */
.pds-chat-panel__scroll {
display: flex;
inset-block-end: var(--pds-spacing-m);
inset-inline: 0;
justify-content: center;
pointer-events: none;
position: absolute;
z-index: 1;
}
.pds-chat-panel__scroll-button.pds-icon-button,
.pds-chat-panel__scroll-button.pds-icon-button:hover:enabled {
background-color: var(--pds-color-surface-default);
box-shadow: var(--pds-elevation-raised);
pointer-events: auto;
}
/* Files dragged over the panel: a faded sheet over the content area with the
file icons and the label. Pointer events pass through so the drag counter
stays accurate. */
.pds-chat-panel__drop {
align-items: center;
display: flex;
flex-direction: column;
gap: var(--pds-spacing-s);
inset: 0;
justify-content: center;
pointer-events: none;
position: absolute;
z-index: 1;
}
.pds-chat-panel__drop::before {
background-color: var(--pds-color-surface-default);
content: '';
inset: 0;
opacity: 0.92;
position: absolute;
}
.pds-chat-panel__drop-icon,
.pds-chat-panel__drop-label {
position: relative;
}
/* Inset: `none` removes the inline padding only. */
.pds-chat-panel__header--inset-default,
.pds-chat-panel__content--inset-default,
.pds-chat-panel__footer--inset-default {
padding-inline: var(--chat-panel-inset);
}
/* Same as the PDS Panel content: l, then xl from the `m` breakpoint. The
custom media query form doesn't work in this repo, so the port restores
`@media (--pds-bp-m)`. */
@media (min-width: 768px) {
.pds-chat-panel {
--chat-panel-inset: var(--pds-spacing-xl);
}
}
Chat Panel
A layout shell for the content of an AI chat drawer or docked side panel.
Net-new componentOpen in Storybook