Skip to content

Commit 8cbb4d5

Browse files
authored
feat(ui): update redpanda-ui to ui-registry v2.1.2 (#2528)
Re-sync all 74 registry components to v2.1.2 (Base UI native API), migrate call sites off the removed compat shim (asChild->render, Accordion/ToggleGroup string[] API, removed transition props, onOpenAutoFocus->initialFocus, resizable direction->orientation), bump recharts->3 and react-resizable-panels->4, add cnfast. v2.1.2 folds in the two fixes Console previously carried locally (button anchor href, code-block React 19 ref type), so button/code-block match the tagged release with no remaining drift.
1 parent c5922b7 commit 8cbb4d5

194 files changed

Lines changed: 4330 additions & 5815 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

frontend/bun.lock

Lines changed: 22 additions & 19 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/package.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,10 +127,10 @@
127127
"react-highlight-words": "^0.21.0",
128128
"react-hook-form": "^7.76.1",
129129
"react-markdown": "^10.1.0",
130-
"react-resizable-panels": "^3.0.6",
130+
"react-resizable-panels": "^4.11.2",
131131
"react-simple-code-editor": "^0.14.1",
132132
"react-syntax-highlighter": "^16.0.0",
133-
"recharts": "^2.15.4",
133+
"recharts": "^3.8.1",
134134
"remark-emoji": "^5.0.2",
135135
"remark-gfm": "^4.0.1",
136136
"shiki": "^3.23.0",
@@ -203,11 +203,15 @@
203203
"dompurify": "^3.4.0",
204204
"prismjs": "^1.30.0",
205205
"baseline-browser-mapping": "2.10.33",
206-
"memoize-one": "^6.0.0"
206+
"memoize-one": "^6.0.0",
207+
"@types/react": "^19.2.17",
208+
"@types/react-dom": "^19.2.3"
207209
},
208210
"resolutions": {
209211
"baseline-browser-mapping": "2.10.33",
210-
"memoize-one": "^6.0.0"
212+
"memoize-one": "^6.0.0",
213+
"@types/react": "^19.2.17",
214+
"@types/react-dom": "^19.2.3"
211215
},
212216
"patchedDependencies": {
213217
"@tanstack/react-router@1.170.15": "patches/@tanstack%2Freact-router@1.170.15.patch"

frontend/src/components/ai-elements/actions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export const Action = ({
5252
return (
5353
<TooltipProvider>
5454
<Tooltip>
55-
<TooltipTrigger asChild>{button}</TooltipTrigger>
55+
<TooltipTrigger render={button} />
5656
<TooltipContent>
5757
<p>{tooltip}</p>
5858
</TooltipContent>

frontend/src/components/ai-elements/artifact.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export const ArtifactAction = ({
125125
return (
126126
<TooltipProvider>
127127
<Tooltip>
128-
<TooltipTrigger asChild>{button}</TooltipTrigger>
128+
<TooltipTrigger render={button} />
129129
<TooltipContent>
130130
<p>{tooltip}</p>
131131
</TooltipContent>

frontend/src/components/ai-elements/context.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
import { Progress } from "components/redpanda-ui/components/progress";
1010
import { cn } from "components/redpanda-ui/lib/utils";
1111
import type { LanguageModelUsage } from "ai";
12-
import { type ComponentProps, createContext, useContext, useMemo } from "react";
12+
import { type ComponentProps, createContext, type ReactElement, useContext, useMemo } from "react";
1313
import { getUsage } from "tokenlens";
1414

1515
const PERCENT_MAX = 100;
@@ -139,16 +139,18 @@ export const ContextTrigger = ({ children, ...props }: ContextTriggerProps) => {
139139
}).format(usedPercent);
140140

141141
return (
142-
<HoverCardTrigger asChild>
143-
{children ?? (
144-
<Button type="button" variant="secondary-ghost" {...props}>
145-
<span className="font-medium text-muted-foreground">
146-
{renderedPercent}
147-
</span>
148-
<ContextIcon />
149-
</Button>
150-
)}
151-
</HoverCardTrigger>
142+
<HoverCardTrigger
143+
render={
144+
(children ?? (
145+
<Button type="button" variant="secondary-ghost" {...props}>
146+
<span className="font-medium text-muted-foreground">
147+
{renderedPercent}
148+
</span>
149+
<ContextIcon />
150+
</Button>
151+
)) as ReactElement
152+
}
153+
/>
152154
);
153155
};
154156

@@ -197,7 +199,7 @@ export const ContextContentHeader = ({
197199
</p>
198200
</div>
199201
<div className="space-y-2">
200-
<Progress className="bg-muted" transition={{ duration: 0 }} value={usedPercent * PERCENT_MAX} />
202+
<Progress className="bg-muted" value={usedPercent * PERCENT_MAX} />
201203
</div>
202204
</>
203205
)}

frontend/src/components/ai-elements/prompt-input.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -956,11 +956,10 @@ export const PromptInputActionMenuTrigger = ({
956956
children,
957957
...props
958958
}: PromptInputActionMenuTriggerProps) => (
959-
<DropdownMenuTrigger asChild>
960-
<PromptInputButton className={className} {...props}>
959+
<DropdownMenuTrigger
960+
render={<PromptInputButton className={className} {...props}>
961961
{children ?? <PlusIcon className="size-4" />}
962-
</PromptInputButton>
963-
</DropdownMenuTrigger>
962+
</PromptInputButton>} />
964963
);
965964

966965
export type PromptInputActionMenuContentProps = ComponentProps<

frontend/src/components/ai-elements/task.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ export const TaskTrigger = ({
6969
<div className="flex w-full cursor-pointer items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground">
7070
<SearchIcon className="size-4" />
7171
<p className="text-sm">{title}</p>
72-
<ChevronDownIcon className="size-4 transition-transform group-data-[state=open]:rotate-180" />
72+
<ChevronDownIcon className="size-4 transition-transform group-data-[panel-open]:rotate-180" />
7373
</div>
7474
)}
7575
</CollapsibleTrigger>
@@ -84,7 +84,6 @@ export const TaskContent = ({
8484
}: TaskContentProps) => (
8585
<CollapsibleContent
8686
className={cn("text-popover-foreground outline-none", className)}
87-
transition={{ duration: 0 }}
8887
{...props}
8988
>
9089
<div className="mt-4 space-y-2 border-muted border-l-2 pl-4">

frontend/src/components/ai-elements/tool.tsx

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ export const ToolHeader = ({
158158
};
159159

160160
return (
161-
<CollapsibleTrigger asChild>
162-
<div
161+
<CollapsibleTrigger
162+
render={<div
163163
className={cn(
164164
"flex w-full cursor-pointer items-center justify-between gap-4 p-3",
165165
className
@@ -192,10 +192,9 @@ export const ToolHeader = ({
192192
onClick={(e) => e.stopPropagation()}
193193
title={toolCallId ? `Copy: ${displayName} (${toolCallId})` : `Copy: ${displayName}`}
194194
/>
195-
<ChevronDownIcon className="size-4 text-muted-foreground transition-transform group-data-[state=open]:rotate-180" />
195+
<ChevronDownIcon className="size-4 text-muted-foreground transition-transform group-data-[panel-open]:rotate-180" />
196196
</div>
197-
</div>
198-
</CollapsibleTrigger>
197+
</div>} />
199198
);
200199
};
201200

@@ -207,7 +206,6 @@ export const ToolContent = ({ className, ...props }: ToolContentProps) => (
207206
"text-popover-foreground outline-none",
208207
className
209208
)}
210-
transition={{ duration: 0 }}
211209
{...props}
212210
/>
213211
);

frontend/src/components/layout/header.tsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,7 @@ function BreadcrumbHeaderRow({ useNewSidebar, breadcrumbItems }: BreadcrumbHeade
5555
<Fragment key={`${index}-${item.linkTo}`}>
5656
{index > 0 && <BreadcrumbSeparator />}
5757
<BreadcrumbItem>
58-
<BreadcrumbLink asChild>
59-
<Link to={item.linkTo}>{item.title}</Link>
60-
</BreadcrumbLink>
58+
<BreadcrumbLink render={<Link to={item.linkTo}>{item.title}</Link>} />
6159
</BreadcrumbItem>
6260
</Fragment>
6361
))}
@@ -109,19 +107,22 @@ function AppPageHeader({ breadcrumbOnly = false }: { breadcrumbOnly?: boolean })
109107
return (
110108
<div>
111109
<BreadcrumbHeaderRow breadcrumbItems={breadcrumbItems} useNewSidebar={useNewSidebar} />
112-
113110
{/* Title + actions row. Hidden for breadcrumb-only headers (e.g. the SQL
114111
studio, which carries its own title bar and toolbar). */}
115112
{!hideTitleRow && (
116113
<div className="flex items-center justify-between pt-6">
117114
<div className="flex flex-col gap-1">
118115
{backLink && (
119-
<RegistryButton asChild className="-ml-2 w-fit text-muted-foreground" variant="ghost">
120-
<Link to={backLink.linkTo}>
121-
<ChevronLeft className="h-4 w-4" />
122-
{backLink.title}
123-
</Link>
124-
</RegistryButton>
116+
<RegistryButton
117+
className="-ml-2 w-fit text-muted-foreground"
118+
render={
119+
<Link to={backLink.linkTo}>
120+
<ChevronLeft className="h-4 w-4" />
121+
{backLink.title}
122+
</Link>
123+
}
124+
variant="ghost"
125+
/>
125126
)}
126127
<div className="flex items-center">
127128
{pageTitle ? (

frontend/src/components/layout/sidebar.tsx

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -114,34 +114,36 @@ const UserProfile = () => {
114114
return (
115115
<>
116116
<DropdownMenu>
117-
<DropdownMenuTrigger asChild>
118-
<SidebarMenuButton
119-
aria-label={`User menu for ${user.displayName}`}
120-
className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
121-
size={isCollapsed ? 'md' : 'lg'}
122-
tooltip={isCollapsed ? user.displayName : undefined}
123-
>
124-
<Avatar className={isCollapsed ? 'h-7 w-7 shrink-0' : 'h-8 w-8 shrink-0'}>
125-
<AvatarImage alt="" src={user.avatarUrl} />
126-
<AvatarFallback aria-hidden="true" className="bg-primary font-medium text-primary-foreground text-xs">
127-
{initials}
128-
</AvatarFallback>
129-
</Avatar>
130-
{!isCollapsed && (
131-
<>
132-
<div className="grid flex-1 text-left leading-tight">
133-
<Text as="span" className="truncate" variant="label">
134-
{user.displayName}
135-
</Text>
136-
<Text as="span" className="truncate text-sidebar-foreground/60" variant="muted">
137-
Preferences
138-
</Text>
139-
</div>
140-
<ChevronUp aria-hidden="true" className="ml-auto size-4" />
141-
</>
142-
)}
143-
</SidebarMenuButton>
144-
</DropdownMenuTrigger>
117+
<DropdownMenuTrigger
118+
render={
119+
<SidebarMenuButton
120+
aria-label={`User menu for ${user.displayName}`}
121+
className="data-[popup-open]:bg-sidebar-accent data-[popup-open]:text-sidebar-accent-foreground"
122+
size={isCollapsed ? 'default' : 'lg'}
123+
tooltip={isCollapsed ? user.displayName : undefined}
124+
>
125+
<Avatar className={isCollapsed ? 'h-7 w-7 shrink-0' : 'h-8 w-8 shrink-0'}>
126+
<AvatarImage alt="" src={user.avatarUrl} />
127+
<AvatarFallback aria-hidden="true" className="bg-primary font-medium text-primary-foreground text-xs">
128+
{initials}
129+
</AvatarFallback>
130+
</Avatar>
131+
{!isCollapsed && (
132+
<>
133+
<div className="grid flex-1 text-left leading-tight">
134+
<Text as="span" className="truncate" variant="label">
135+
{user.displayName}
136+
</Text>
137+
<Text as="span" className="truncate text-sidebar-foreground/60" variant="muted">
138+
Preferences
139+
</Text>
140+
</div>
141+
<ChevronUp aria-hidden="true" className="ml-auto size-4" />
142+
</>
143+
)}
144+
</SidebarMenuButton>
145+
}
146+
/>
145147
<DropdownMenuContent align="end" className="w-56 rounded-lg" side={isMobile ? 'bottom' : 'top'}>
146148
<DropdownMenuLabel>
147149
<div className="flex flex-col">
@@ -175,7 +177,6 @@ const UserProfile = () => {
175177
</DropdownMenuItem>
176178
</DropdownMenuContent>
177179
</DropdownMenu>
178-
179180
<UserPreferencesDialog isOpen={preferencesOpen} onClose={() => setPreferencesOpen(false)} />
180181
</>
181182
);
@@ -203,19 +204,17 @@ function SidebarNavItem({ item, isActive, onNavClick }: NavItemProps) {
203204
<SidebarMenuButton
204205
aria-current={isActive ? 'page' : undefined}
205206
aria-disabled={item.isDisabled}
206-
asChild={!item.isDisabled}
207207
className={item.isDisabled ? 'cursor-not-allowed opacity-50' : ''}
208208
disabled={item.isDisabled}
209209
isActive={isActive}
210+
render={
211+
item.isDisabled ? undefined : (
212+
<Link aria-current={isActive ? 'page' : undefined} onClick={onNavClick} to={item.to} />
213+
)
214+
}
210215
tooltip={item.isDisabled ? { children: item.disabledText } : titleString}
211216
>
212-
{item.isDisabled ? (
213-
<span className="flex items-center gap-2">{itemContent}</span>
214-
) : (
215-
<Link aria-current={isActive ? 'page' : undefined} onClick={onNavClick} to={item.to}>
216-
{itemContent}
217-
</Link>
218-
)}
217+
{item.isDisabled ? <span className="flex items-center gap-2">{itemContent}</span> : itemContent}
219218
</SidebarMenuButton>
220219
</SidebarMenuItem>
221220
);

0 commit comments

Comments
 (0)