Skip to content

Commit 3cd9fab

Browse files
authored
Merge pull request #1923 from redpanda-data/master
Release 3.2: update with css fixes
2 parents be7c6c7 + 3680f37 commit 3cd9fab

File tree

14 files changed

+660
-506
lines changed

14 files changed

+660
-506
lines changed

frontend/src/components/redpanda-ui/components/button.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ const Button = React.forwardRef<
5353
data-slot="button"
5454
data-testid={testId}
5555
className={cn(
56-
className,
5756
buttonVariants({ variant, size, className }),
5857
attached && position === 'first'
5958
? 'rounded-r-none rounded-l-md border-r-0'
6059
: attached && position === 'last'
6160
? 'rounded-l-none rounded-r-md border-l-0'
6261
: attached && position === 'middle'
6362
? 'rounded-none border-l-0 border-r-0'
64-
: 'rounded-md'
63+
: 'rounded-md',
64+
className,
6565
)}
6666
{...props}
6767
/>

frontend/src/components/redpanda-ui/components/card.tsx

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import { cva, type VariantProps } from 'class-variance-authority';
22
import React from 'react';
33

4+
import { Heading, Text } from './typography';
45
import { cn } from '../lib/utils';
56

67
const cardVariants = cva(
7-
'rounded-lg min-w-0 border border-solid bg-white border-base-200 flex flex-col shadow-shadow-elevated dark:bg-base-900 dark:border-base-800',
8+
'rounded-lg min-w-0 border border-solid bg-white border-base-200 flex flex-col shadow-elevated dark:bg-base-900 dark:border-base-800',
89
{
910
variants: {
1011
size: {
11-
sm: 'px-12 py-8 gap-4 max-w-sm',
12-
md: 'px-16 py-12 gap-5 max-w-md',
13-
lg: 'px-20 py-16 gap-6 max-w-lg',
14-
xl: 'px-24 py-20 gap-8 max-w-xl',
15-
full: 'px-16 py-12 gap-5 w-full',
12+
sm: 'px-6 py-4 gap-2 max-w-sm',
13+
md: 'px-8 py-6 gap-4 max-w-md',
14+
lg: 'px-10 py-8 gap-4 max-w-lg',
15+
xl: 'px-12 py-10 gap-6 max-w-xl',
16+
full: 'px-8 py-6 gap-4 w-full',
1617
},
1718
variant: {
1819
default: '',
@@ -28,7 +29,7 @@ const cardVariants = cva(
2829
},
2930
);
3031

31-
interface CardProps extends React.ComponentProps<'div'>, VariantProps<typeof cardVariants> {
32+
export interface CardProps extends React.ComponentProps<'div'>, VariantProps<typeof cardVariants> {
3233
testId?: string;
3334
}
3435

@@ -89,32 +90,31 @@ const CardHeader = React.forwardRef<HTMLDivElement, CardHeaderProps>(
8990

9091
CardHeader.displayName = 'CardHeader';
9192

92-
const CardTitle = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'> & { testId?: string }>(
93-
({ className, testId, ...props }, ref) => {
94-
return (
95-
<div
96-
ref={ref}
97-
data-slot="card-title"
98-
data-testid={testId}
99-
className={cn('leading-none font-semibold', className)}
100-
{...props}
101-
/>
102-
);
103-
},
104-
);
93+
const CardTitle = React.forwardRef<
94+
HTMLHeadingElement,
95+
React.ComponentProps<'div'> & { testId?: string; level?: 1 | 2 | 3 | 4 }
96+
>(({ className, level = 4, testId, children, ...props }, ref) => {
97+
return (
98+
<div ref={ref} data-slot="card-title" data-testid={testId} className={className} {...props}>
99+
{typeof children === 'string' ? <Heading level={level}>{children}</Heading> : children}
100+
</div>
101+
);
102+
});
105103

106104
CardTitle.displayName = 'CardTitle';
107105

108106
const CardDescription = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'> & { testId?: string }>(
109-
({ className, testId, ...props }, ref) => {
107+
({ className, testId, children, ...props }, ref) => {
110108
return (
111109
<div
112110
ref={ref}
113111
data-slot="card-description"
114112
data-testid={testId}
115113
className={cn('text-muted-foreground text-sm', className)}
116114
{...props}
117-
/>
115+
>
116+
{typeof children === 'string' ? <Text>{children}</Text> : children}
117+
</div>
118118
);
119119
},
120120
);
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { Circle } from 'lucide-react';
2+
import { AnimatePresence, motion, type Transition } from 'motion/react';
3+
import { RadioGroup as RadioGroupPrimitive } from 'radix-ui';
4+
import type { ComponentProps, HTMLAttributes } from 'react';
5+
6+
import { Card, CardContent, CardDescription, CardHeader, type CardProps, CardTitle } from './card';
7+
import { RadioGroup } from './radio-group';
8+
import { cn } from '../lib/utils';
9+
10+
export type ChoiceboxProps = ComponentProps<typeof RadioGroup> & { testId?: string };
11+
12+
export const Choicebox = ({ className, testId, ...props }: ChoiceboxProps) => (
13+
<RadioGroup className={cn('w-full', className)} data-testid={testId} {...props} />
14+
);
15+
16+
export type ChoiceboxItemProps = RadioGroupPrimitive.RadioGroupItemProps & { testId?: string } & Partial<
17+
Pick<CardProps, 'size'>
18+
>;
19+
20+
export const ChoiceboxItem = ({ className, children, testId, size, ...props }: ChoiceboxItemProps) => (
21+
<RadioGroupPrimitive.Item {...props}>
22+
<Card
23+
size={size}
24+
className={cn(
25+
'flex cursor-pointer flex-row items-start justify-between rounded-md p-4 shadow-none transition-all border-2 border-solid !border-border text-left',
26+
'[&[data-state="checked"]]:border-selected',
27+
'[&[data-state="checked"]]:bg-selected/5',
28+
'hover:shadow-elevated',
29+
className,
30+
)}
31+
data-testid={testId}
32+
>
33+
{children}
34+
</Card>
35+
</RadioGroupPrimitive.Item>
36+
);
37+
38+
export type ChoiceboxItemHeaderProps = ComponentProps<typeof CardHeader>;
39+
40+
export const ChoiceboxItemHeader = ({ className, ...props }: ComponentProps<typeof CardHeader>) => (
41+
<CardHeader className={cn('flex-1 p-0', className)} {...props} />
42+
);
43+
44+
export type ChoiceboxItemTitleProps = ComponentProps<typeof CardTitle>;
45+
46+
export const ChoiceboxItemTitle = ({ className, ...props }: ChoiceboxItemTitleProps) => (
47+
<CardTitle className={cn('flex items-center gap-3', className)} {...props} />
48+
);
49+
50+
export type ChoiceboxItemSubtitleProps = HTMLAttributes<HTMLSpanElement>;
51+
52+
export const ChoiceboxItemSubtitle = ({ className, ...props }: ChoiceboxItemSubtitleProps) => (
53+
<span className={cn('font-normal text-muted-foreground text-xs', className)} {...props} />
54+
);
55+
56+
export type ChoiceboxItemDescriptionProps = ComponentProps<typeof CardDescription>;
57+
58+
export const ChoiceboxItemDescription = ({ className, ...props }: ChoiceboxItemDescriptionProps) => (
59+
<CardDescription className={cn('text-sm', className)} {...props} />
60+
);
61+
62+
export type ChoiceboxItemContentProps = ComponentProps<typeof CardContent>;
63+
64+
export const ChoiceboxItemContent = ({ className, ...props }: ChoiceboxItemContentProps) => (
65+
<CardContent
66+
className={cn(
67+
'flex aspect-square size-4 shrink-0 items-center justify-center rounded-full border border-input p-0 text-selected shadow-xs outline-none transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30 dark:aria-invalid:ring-destructive/40',
68+
className,
69+
)}
70+
{...props}
71+
/>
72+
);
73+
74+
export type ChoiceboxItemIndicatorProps = ComponentProps<typeof RadioGroupPrimitive.Indicator> & {
75+
transition?: Transition;
76+
};
77+
78+
export const ChoiceboxItemIndicator = ({
79+
className,
80+
transition = { type: 'spring', stiffness: 200, damping: 16 },
81+
...props
82+
}: ChoiceboxItemIndicatorProps) => (
83+
<RadioGroupPrimitive.Indicator
84+
data-slot="radio-group-indicator"
85+
className={cn('flex items-center justify-center', className)}
86+
{...props}
87+
>
88+
<AnimatePresence>
89+
<motion.div
90+
key="radio-group-indicator-circle"
91+
data-slot="radio-group-indicator-circle"
92+
initial={{ opacity: 0, scale: 0 }}
93+
animate={{ opacity: 1, scale: 1 }}
94+
exit={{ opacity: 0, scale: 0 }}
95+
transition={transition}
96+
>
97+
<Circle className="size-2.5 fill-current text-current" />
98+
</motion.div>
99+
</AnimatePresence>
100+
</RadioGroupPrimitive.Indicator>
101+
);

0 commit comments

Comments
 (0)