Skip to content

Commit 3aa0d9a

Browse files
authored
fix(dropdown): limit content height to available viewport space (#609)
1 parent 25b2ab1 commit 3aa0d9a

4 files changed

Lines changed: 42 additions & 1 deletion

File tree

.changeset/fair-ways-remember.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/kumo": patch
3+
---
4+
5+
Limit Dropdown content height to available viewport space to prevent overflow.

packages/kumo-docs-astro/src/components/demos/DropdownDemo.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,24 @@ export function DropdownAvatarTriggerDemo() {
238238
);
239239
}
240240

241+
/**
242+
* A dropdown with a very long list of items to demonstrate the max-height
243+
* behavior — the content scrolls when it exceeds available viewport space.
244+
*/
245+
export function DropdownLongListDemo() {
246+
const items = Array.from({ length: 30 }, (_, i) => `Option ${i + 1}`);
247+
248+
return (
249+
<DropdownMenu>
250+
<DropdownMenu.Trigger render={<Button>Open long list</Button>} />
251+
<DropdownMenu.Content>
252+
{items.map((item) => (
253+
<DropdownMenu.Item key={item}>{item}</DropdownMenu.Item>
254+
))}
255+
</DropdownMenu.Content>
256+
</DropdownMenu>
257+
);
258+
}
241259
/**
242260
* Demonstrates the new LinkItem component for navigation links.
243261
* Use LinkItem instead of Item with href for cleaner, more semantic links.

packages/kumo-docs-astro/src/pages/components/dropdown.mdx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
DropdownNestedDemo,
1818
DropdownAvatarTriggerDemo,
1919
DropdownLinkItemDemo,
20+
DropdownLongListDemo,
2021
} from "~/components/demos/DropdownDemo";
2122

2223
{/* Hero Demo */}
@@ -155,6 +156,16 @@ export default function Example() {
155156
<DropdownLinkItemDemo client:load />
156157
</ComponentExample>
157158

159+
### Long List
160+
161+
<p>
162+
When a dropdown contains many items, the content automatically limits its height
163+
to the available viewport space and becomes scrollable.
164+
</p>
165+
<ComponentExample demo="DropdownLongListDemo">
166+
<DropdownLongListDemo client:load />
167+
</ComponentExample>
168+
158169
</ComponentSection>
159170

160171
{/* API Reference */}

packages/kumo/src/components/dropdown/dropdown.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@ export interface KumoDropdownVariantsProps {
4949
export function dropdownVariants({
5050
variant = KUMO_DROPDOWN_DEFAULT_VARIANTS.variant,
5151
}: KumoDropdownVariantsProps = {}) {
52-
return cn(resolveVariant(KUMO_DROPDOWN_VARIANTS.variant, variant, KUMO_DROPDOWN_DEFAULT_VARIANTS.variant).classes);
52+
return cn(
53+
resolveVariant(
54+
KUMO_DROPDOWN_VARIANTS.variant,
55+
variant,
56+
KUMO_DROPDOWN_DEFAULT_VARIANTS.variant,
57+
).classes,
58+
);
5359
}
5460

5561
const DropdownMenuSubTrigger = React.forwardRef<
@@ -112,6 +118,7 @@ const DropdownMenuContent = React.forwardRef<
112118
<DropdownMenuPrimitive.Popup
113119
className={cn(
114120
"overflow-hidden bg-kumo-control text-kumo-default", // background
121+
"max-h-[var(--available-height)] overflow-y-auto", // limit height when list is too long and might go off screen
115122
"rounded-lg shadow-lg ring ring-kumo-line", // border part
116123
"min-w-36 p-1.5", // spacing
117124
"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", // open animation

0 commit comments

Comments
 (0)