Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ export function LayerDialogAlertDemo() {
<LayerDialog.Content>
<LayerDialog.Title>Delete Worker</LayerDialog.Title>
<LayerDialog.Description>
Deleting <strong className="text-kumo-default">{workerName}</strong>{" "}
Deleting{" "}
<strong className="font-medium text-kumo-default">
{workerName}
</strong>{" "}
is permanent.
</LayerDialog.Description>
<LayerDialog.Body>
Expand All @@ -155,7 +158,11 @@ export function LayerDialogAlertDemo() {
<Input
label={
<>
Type <strong>{workerName}</strong> to confirm
Type{" "}
<strong className="font-medium text-kumo-default">
{workerName}
</strong>{" "}
to confirm
</>
}
onChange={(event) => setConfirmation(event.target.value)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Consumers cannot mix these layouts or add more primary actions. Use the X for re

<ComponentSection>
## Informational dialog
`Title` and `Description` always live in the bordered body surface. The title frame remains visible while the body scrolls, gains a bottom border after scrolling, and has the sole automatic X dismissal action. Once the body scrolls past the top, the description folds away beneath the title to give the content more room, and unfolds again at the top. The content edge mask signals overflow.
`Title` and `Description` always live in the bordered body surface. The title frame remains visible while the body scrolls and has the sole automatic X dismissal action. Once the body scrolls past the top, the description folds away beneath the title to give the content more room, and unfolds again at the top. The content edge mask signals overflow.
<ComponentExample demo="LayerDialogInformationalDemo"><LayerDialogInformationalDemo client:load /></ComponentExample>
</ComponentSection>

Expand Down
36 changes: 19 additions & 17 deletions packages/kumo/src/components/layer-dialog/layer-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,12 @@ export interface LayerDialogTitleProps {

function LayerDialogTitle({ children }: LayerDialogTitleProps) {
const title = (props: ComponentPropsWithoutRef<"h2">) => (
<Text {...props} as="h2" variant="heading">
<Text
{...props}
as="h2"
variant="heading"
DANGEROUS_className="font-medium"
>
{children}
</Text>
);
Expand Down Expand Up @@ -360,13 +365,12 @@ export interface LayerDialogBodyProps {
children: ReactNode;
}

/** Scroll distance before the header shows its divider and condenses. */
/** Scroll distance before the header description condenses. */
const SCROLL_THRESHOLD = 8;
/** Overflow that must remain after the description collapses (see handleScroll). */
const CONDENSE_MIN_OVERFLOW = 16;

function LayerDialogBody({ children }: LayerDialogBodyProps) {
const [hasScrolled, setHasScrolled] = useState(false);
const [condensed, setCondensed] = useState(false);
const descriptionClipRef = useRef<HTMLDivElement>(null);
const dismissDisabled = useContext(DismissDisabledContext);
Expand All @@ -376,7 +380,6 @@ function LayerDialogBody({ children }: LayerDialogBodyProps) {
const handleScroll = (event: UIEvent<HTMLDivElement>) => {
const { scrollTop, scrollHeight, clientHeight } = event.currentTarget;
const scrolled = scrollTop > SCROLL_THRESHOLD;
setHasScrolled(scrolled);

if (!scrolled) {
setCondensed(false);
Expand Down Expand Up @@ -404,15 +407,8 @@ function LayerDialogBody({ children }: LayerDialogBodyProps) {
);

return (
<LayerCard.Primary className="min-h-0 flex-1 !gap-0 overflow-hidden border border-kumo-line !p-0 !ring-0">
<div
className={cn(
"z-10 flex shrink-0 items-start justify-between gap-4 bg-kumo-base px-4 py-4 transition-[border-color]",
hasScrolled
? "border-b border-kumo-line"
: "border-b border-transparent",
)}
>
<LayerCard.Primary className="min-h-0 flex-1 gap-0 p-0">
<div className="z-10 flex shrink-0 items-start justify-between gap-4 rounded-t-lg bg-kumo-base px-4.5 py-4">
<div className="flex min-w-0 flex-col">
{title}
{description && (
Expand Down Expand Up @@ -443,7 +439,7 @@ function LayerDialogBody({ children }: LayerDialogBodyProps) {
className="min-h-0 flex-1 overscroll-none [mask-image:linear-gradient(to_bottom,transparent_0,black_min(24px,var(--scroll-area-overflow-y-start,24px)),black_calc(100%-min(24px,var(--scroll-area-overflow-y-end,24px))),transparent_100%)]"
onScroll={handleScroll}
>
<ScrollAreaBase.Content className="px-4 pb-4">
<ScrollAreaBase.Content className="px-4.5 pb-4.5">
{content}
</ScrollAreaBase.Content>
</ScrollAreaBase.Viewport>
Expand Down Expand Up @@ -472,8 +468,9 @@ function LayerDialogIconClose({
<Button
{...closeProps}
aria-label={label}
className="-mt-1.5 -mr-1.5 rounded-lg"
disabled={disabled}
icon={X}
icon={<X size={15} />}
shape="square"
size="sm"
variant="ghost"
Expand Down Expand Up @@ -541,7 +538,7 @@ const LayerDialogActions = Object.assign(
}

return (
<div className="flex w-full shrink-0 items-center justify-between gap-2 pt-2 pb-1">
<div className="flex w-full shrink-0 items-center justify-between gap-2 pt-1.75">
<LayerDialogDismiss disabled={dismissDisabled} label={label} />
{children}
</div>
Expand All @@ -561,7 +558,12 @@ function LayerDialogDismiss({
label: string;
}) {
const close = (closeProps: ComponentPropsWithoutRef<"button">) => (
<Button {...closeProps} disabled={disabled} variant="ghost">
<Button
{...closeProps}
className="hover:bg-kumo-fill/50"
disabled={disabled}
variant="ghost"
>
{label}
</Button>
);
Expand Down
Loading