Skip to content

Commit a74bd9c

Browse files
authored
fix(dialog): use fixed width instead of min-width for size prop (#601)
1 parent 8463c38 commit a74bd9c

4 files changed

Lines changed: 125 additions & 13 deletions

File tree

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+
Fix Dialog `size` prop to set a fixed width instead of only a minimum width. Previously, dialog content could stretch the dialog beyond its intended size.

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

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
Combobox,
77
DropdownMenu,
88
} from "@cloudflare/kumo";
9+
import type { DialogProps } from "@cloudflare/kumo";
910
import { Warning, X } from "@phosphor-icons/react";
1011

1112
export function DialogBasicDemo() {
@@ -383,3 +384,97 @@ export function DialogWithDropdownDemo() {
383384
</Dialog.Root>
384385
);
385386
}
387+
388+
/**
389+
* Demonstrates that each dialog size holds its fixed width regardless of
390+
* content. Each dialog contains a wide table that would previously cause the
391+
* dialog to stretch beyond its intended size.
392+
*/
393+
export function DialogSizesDemo() {
394+
const sizes: { size: NonNullable<DialogProps["size"]>; label: string; width: string }[] = [
395+
{ size: "sm", label: "Small", width: "288px" },
396+
{ size: "base", label: "Base", width: "384px" },
397+
{ size: "lg", label: "Large", width: "512px" },
398+
{ size: "xl", label: "Extra Large", width: "768px" },
399+
];
400+
401+
return (
402+
<div className="flex flex-wrap gap-2">
403+
{sizes.map(({ size, label, width }) => (
404+
<Dialog.Root key={size}>
405+
<Dialog.Trigger
406+
render={(p) => (
407+
<Button variant="secondary" {...p}>
408+
{label} ({width})
409+
</Button>
410+
)}
411+
/>
412+
<Dialog size={size} className="p-8">
413+
<div className="mb-4 flex items-start justify-between gap-4">
414+
<Dialog.Title className="text-2xl font-semibold">
415+
{label} Dialog
416+
</Dialog.Title>
417+
<Dialog.Close
418+
aria-label="Close"
419+
render={(props) => (
420+
<Button
421+
{...props}
422+
variant="secondary"
423+
shape="square"
424+
icon={<X />}
425+
aria-label="Close"
426+
/>
427+
)}
428+
/>
429+
</div>
430+
<Dialog.Description className="text-kumo-subtle">
431+
This <code>size="{size}"</code> dialog should stay at {width} wide
432+
regardless of the content below.
433+
</Dialog.Description>
434+
<div className="mt-4 overflow-auto rounded-md border border-kumo-line">
435+
<table className="w-max text-sm">
436+
<thead className="bg-kumo-elevated text-left">
437+
<tr>
438+
<th className="px-3 py-2">Resource</th>
439+
<th className="px-3 py-2">Region</th>
440+
<th className="px-3 py-2">Status</th>
441+
<th className="px-3 py-2">Latency</th>
442+
<th className="px-3 py-2">Requests</th>
443+
<th className="px-3 py-2">Last Deployed</th>
444+
</tr>
445+
</thead>
446+
<tbody className="divide-y divide-kumo-hairline">
447+
<tr>
448+
<td className="px-3 py-2">api-gateway-prod</td>
449+
<td className="px-3 py-2">us-east-1</td>
450+
<td className="px-3 py-2 text-kumo-success">Healthy</td>
451+
<td className="px-3 py-2">12ms</td>
452+
<td className="px-3 py-2">1,234,567</td>
453+
<td className="px-3 py-2">2026-06-23</td>
454+
</tr>
455+
<tr>
456+
<td className="px-3 py-2">worker-analytics</td>
457+
<td className="px-3 py-2">eu-west-1</td>
458+
<td className="px-3 py-2 text-kumo-warning">Degraded</td>
459+
<td className="px-3 py-2">89ms</td>
460+
<td className="px-3 py-2">456,789</td>
461+
<td className="px-3 py-2">2026-06-22</td>
462+
</tr>
463+
</tbody>
464+
</table>
465+
</div>
466+
<div className="mt-6 flex justify-end gap-2">
467+
<Dialog.Close
468+
render={(props) => (
469+
<Button variant="secondary" {...props}>
470+
Close
471+
</Button>
472+
)}
473+
/>
474+
</div>
475+
</Dialog>
476+
</Dialog.Root>
477+
))}
478+
</div>
479+
);
480+
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
DialogConfirmationDemo,
1717
DialogAlertDemo,
1818
DialogMaxWidthDemo,
19+
DialogSizesDemo,
1920
DialogWithSelectDemo,
2021
DialogWithComboboxDemo,
2122
DialogWithDropdownDemo,
@@ -135,6 +136,17 @@ export default function Example() {
135136
<DialogBasicDemo client:load />
136137
</ComponentExample>
137138

139+
### Sizes
140+
141+
<p>
142+
The `size` prop controls the fixed width of the dialog on desktop. Content
143+
that overflows the dialog width will scroll horizontally within the dialog
144+
rather than stretching it.
145+
</p>
146+
<ComponentExample demo="DialogSizesDemo">
147+
<DialogSizesDemo client:load />
148+
</ComponentExample>
149+
138150
### Alert Dialog (`role="alertdialog"`)
139151

140152
<p>

packages/kumo/src/components/dialog/dialog.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@ import {
1919
export const KUMO_DIALOG_VARIANTS = {
2020
size: {
2121
base: {
22-
classes: "sm:min-w-96",
23-
description: "Default dialog width",
22+
classes: "sm:w-96",
23+
description: "Default dialog width (384px)",
2424
},
2525
sm: {
26-
classes: "min-w-72",
27-
description: "Small dialog for simple confirmations",
26+
classes: "sm:w-72",
27+
description: "Small dialog for simple confirmations (288px)",
2828
},
2929
lg: {
30-
classes: "min-w-[32rem]",
31-
description: "Large dialog for complex content",
30+
classes: "sm:w-[32rem]",
31+
description: "Large dialog for complex content (512px)",
3232
},
3333
xl: {
34-
classes: "min-w-[48rem]",
35-
description: "Extra large dialog for detailed views",
34+
classes: "sm:w-[48rem]",
35+
description: "Extra large dialog for detailed views (768px)",
3636
},
3737
},
3838
role: {
@@ -119,10 +119,10 @@ export type KumoDialogRole = keyof typeof KUMO_DIALOG_VARIANTS.role;
119119
export interface KumoDialogVariantsProps {
120120
/**
121121
* Dialog width.
122-
* - `"sm"` — Small (min 288px) for simple confirmations
123-
* - `"base"` — Default (min 384px)
124-
* - `"lg"` — Large (min 512px) for complex content
125-
* - `"xl"` — Extra large (min 768px) for detailed views
122+
* - `"sm"` — Small (288px) for simple confirmations
123+
* - `"base"` — Default (384px)
124+
* - `"lg"` — Large (512px) for complex content
125+
* - `"xl"` — Extra large (768px) for detailed views
126126
* @default "base"
127127
*/
128128
size?: KumoDialogSize;
@@ -143,7 +143,7 @@ export function dialogVariants({
143143
}: KumoDialogVariantsProps = {}) {
144144
return cn(
145145
// Base styles
146-
"shadow-m ring ring-kumo-line fixed top-1/2 left-1/2 w-full sm:w-auto max-w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-xl bg-kumo-base text-kumo-default duration-150 data-ending-style:scale-90 data-ending-style:opacity-0 data-starting-style:scale-90 data-starting-style:opacity-0",
146+
"shadow-m ring ring-kumo-line fixed top-1/2 left-1/2 w-full max-w-[calc(100vw-2rem)] -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-xl bg-kumo-base text-kumo-default duration-150 data-ending-style:scale-90 data-ending-style:opacity-0 data-starting-style:scale-90 data-starting-style:opacity-0",
147147
// Apply size from KUMO_DIALOG_VARIANTS
148148
resolveVariant(KUMO_DIALOG_VARIANTS.size, size, KUMO_DIALOG_DEFAULT_VARIANTS.size).classes,
149149
);

0 commit comments

Comments
 (0)