DTCard: make progress optional, fill top-to-bottom
Progress bar now fills top-down (was bottom-up). When progress prop is
omitted the bar stays empty and the card renders at full size. Only cards
that explicitly pass progress={0–100} show the animated bar.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
*
|
||||
* The progress bar is a structural element on the left edge (0 to bevel-sm).
|
||||
* It is always present. At 0 progress it shows surface color (empty bar).
|
||||
* As progress increases, accent color fills from the bottom up.
|
||||
* As progress increases, accent color fills from top to bottom.
|
||||
* When progress is omitted, the bar stays empty (full card, no fill).
|
||||
*/
|
||||
|
||||
import type { ReactNode, CSSProperties } from 'react';
|
||||
@@ -22,8 +23,14 @@ interface DTCardProps {
|
||||
title?: string;
|
||||
/** Whether to show the accent header bar @default true when title is provided */
|
||||
showHeader?: boolean;
|
||||
/** Progress value (0–100) for left-edge vertical progress bar @default 0 */
|
||||
/** Dismiss callback — renders a close button in the header bar */
|
||||
onDismiss?: () => void;
|
||||
/** Progress value (0–100) for left-edge vertical progress bar. Omit for empty bar. */
|
||||
progress?: number;
|
||||
/** Grow to fill available space in flex/grid containers @default false */
|
||||
grow?: boolean;
|
||||
/** Which area expands when grow is true @default 'body' */
|
||||
growArea?: 'body' | 'title';
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
onClick?: () => void;
|
||||
@@ -34,12 +41,15 @@ export function DTCard({
|
||||
variant = 'normal',
|
||||
title,
|
||||
showHeader,
|
||||
progress = 0,
|
||||
onDismiss,
|
||||
progress,
|
||||
grow = false,
|
||||
growArea = 'body',
|
||||
className,
|
||||
style,
|
||||
onClick,
|
||||
}: DTCardProps) {
|
||||
const shouldShowHeader = showHeader ?? !!title;
|
||||
const shouldShowHeader = showHeader ?? !!(title || onDismiss);
|
||||
const Tag = onClick ? 'button' : 'div';
|
||||
|
||||
return (
|
||||
@@ -47,17 +57,36 @@ export function DTCard({
|
||||
className={cx(
|
||||
'card',
|
||||
getVariantClass(variant),
|
||||
grow && 'dt-card-grow',
|
||||
grow && growArea === 'title' && 'dt-card-grow-title',
|
||||
className,
|
||||
)}
|
||||
style={{
|
||||
...style,
|
||||
'--dt-card-progress': progress,
|
||||
...(progress != null && { '--dt-card-progress': progress }),
|
||||
} as CSSProperties}
|
||||
onClick={onClick}
|
||||
type={onClick ? 'button' : undefined}>
|
||||
{shouldShowHeader && (
|
||||
<div className="card-title">
|
||||
{title}
|
||||
<div className="card-title" style={onDismiss ? { display: 'flex', justifyContent: 'space-between', alignItems: 'center' } : undefined}>
|
||||
<span>{title}</span>
|
||||
{onDismiss && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={(e) => { e.stopPropagation(); onDismiss(); }}
|
||||
aria-label="Close"
|
||||
style={{
|
||||
background: 'none',
|
||||
border: 'none',
|
||||
color: 'inherit',
|
||||
cursor: 'pointer',
|
||||
padding: 0,
|
||||
fontSize: '1.25rem',
|
||||
lineHeight: 1,
|
||||
}}>
|
||||
✕
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{children}
|
||||
|
||||
Reference in New Issue
Block a user