authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-22 12:22:12-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-22 12:22:12-07:00
logb4f1f18b735679aedc4369190fc3f07ecaf8966c
treea0ca6576044032553be36948622dc0ca221b75ec
parent9515016166f926968dacaefc69e2ea0af63942ae
signature Signed by PGP key B5690EEEBB952194

refactor(web): add radius="none" to ScrollArea (#13026)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

9 files changed, 25 insertions(+), 18 deletions(-)

apps/web/src/components/ChatMarkdown.tsx+1-1
...@@ -772,7 +772,7 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) {...@@ -772,7 +772,7 @@ function MarkdownTable({ children, ...props }: React.ComponentProps<"table">) {
772 className="chat-markdown-table-container"772 className="chat-markdown-table-container"
773 data-expanded={expanded ? "true" : "false"}773 data-expanded={expanded ? "true" : "false"}
774 >774 >
775 <ScrollArea chainVerticalScroll scrollFade className="w-full max-w-full rounded-none">775 <ScrollArea radius="none" chainVerticalScroll scrollFade className="w-full max-w-full">
776 <table ref={tableRef} {...props}>776 <table ref={tableRef} {...props}>
777 {children}777 {children}
778 </table>778 </table>
apps/web/src/components/RightPanelTabs.tsx+2-1
...@@ -1127,10 +1127,11 @@ export function RightPanelTabs(props: RightPanelTabsProps) {...@@ -1127,10 +1127,11 @@ export function RightPanelTabs(props: RightPanelTabsProps) {
1127 data-right-panel-tabbar1127 data-right-panel-tabbar
1128 >1128 >
1129 <ScrollArea1129 <ScrollArea
1130 radius="none"
1130 ref={tabListRef}1131 ref={tabListRef}
1131 hideScrollbars1132 hideScrollbars
1132 scrollFade1133 scrollFade
1133 className="min-w-0 flex-1 rounded-none"1134 className="min-w-0 flex-1"
1134 data-right-panel-tab-list1135 data-right-panel-tab-list
1135 >1136 >
1136 <div className="flex h-full w-max min-w-full items-center gap-1">1137 <div className="flex h-full w-max min-w-full items-center gap-1">
apps/web/src/components/chat/ComposerBanner.tsx+2-1
...@@ -282,9 +282,10 @@ function Children({ className, render, ...props }: useRender.ComponentProps<"div...@@ -282,9 +282,10 @@ function Children({ className, render, ...props }: useRender.ComponentProps<"div
282function Scroll({ className, ...props }: ComponentProps<typeof ScrollArea>) {282function Scroll({ className, ...props }: ComponentProps<typeof ScrollArea>) {
283 return (283 return (
284 <ScrollArea284 <ScrollArea
285 radius="none"
285 scrollFade286 scrollFade
286 className={cn(287 className={cn(
287 "h-auto max-h-[min(24rem,40dvh)] rounded-none [&>[data-slot=scroll-area-viewport][data-has-overflow-y]]:pe-2",288 "h-auto max-h-[min(24rem,40dvh)] [&>[data-slot=scroll-area-viewport][data-has-overflow-y]]:pe-2",
288 className,289 className,
289 )}290 )}
290 {...props}291 {...props}
apps/web/src/components/files/FilePreviewPanel.tsx+2-1
...@@ -1090,10 +1090,11 @@ export default function FilePreviewPanel({...@@ -1090,10 +1090,11 @@ export default function FilePreviewPanel({
1090 {relativePath && attachment === undefined ? (1090 {relativePath && attachment === undefined ? (
1091 <div className={FILE_SURFACE_SUBHEADER_CLASS} data-surface-subheader>1091 <div className={FILE_SURFACE_SUBHEADER_CLASS} data-surface-subheader>
1092 <ScrollArea1092 <ScrollArea
1093 radius="none"
1093 ref={breadcrumbRef}1094 ref={breadcrumbRef}
1094 hideScrollbars1095 hideScrollbars
1095 scrollFade1096 scrollFade
1096 className="min-w-0 flex-1 rounded-none"1097 className="min-w-0 flex-1"
1097 data-file-breadcrumbs1098 data-file-breadcrumbs
1098 >1099 >
1099 <div className="flex h-full w-max min-w-full items-center text-xs">1100 <div className="flex h-full w-max min-w-full items-center text-xs">
apps/web/src/components/onboarding/WelcomeWizard.tsx+2-8
...@@ -636,10 +636,7 @@ function AgentsStep({...@@ -636,10 +636,7 @@ function AgentsStep({
636 const { environments } = useEnvironments();636 const { environments } = useEnvironments();
637 return (637 return (
638 <StepShell title="Your agents" description="Agents available on your selected computers.">638 <StepShell title="Your agents" description="Agents available on your selected computers.">
639 <ScrollArea639 <ScrollArea scrollFade className="mt-5 h-auto max-h-96">
640 scrollFade
641 className="mt-5 h-auto max-h-96 [&_[data-slot=scroll-area-scrollbar]]:opacity-100"
642 >
643 <div className="space-y-5 pr-3">640 <div className="space-y-5 pr-3">
644 {environmentIds.map((environmentId) => (641 {environmentIds.map((environmentId) => (
645 <ConnectedAgentsStep642 <ConnectedAgentsStep
...@@ -1206,10 +1203,7 @@ function ImportStep({...@@ -1206,10 +1203,7 @@ function ImportStep({
1206 </div>1203 </div>
1207 </div>1204 </div>
1208 ) : null}1205 ) : null}
1209 <ScrollArea1206 <ScrollArea scrollFade className="mt-2 h-auto max-h-80">
1210 scrollFade
1211 className="mt-2 h-auto max-h-80 [&_[data-slot=scroll-area-scrollbar]]:opacity-100"
1212 >
1213 <div className="space-y-5 pr-3">1207 <div className="space-y-5 pr-3">
1214 {scans.map((scan) => {1208 {scans.map((scan) => {
1215 const scanCandidates = candidates.filter(1209 const scanCandidates = candidates.filter(
apps/web/src/components/settings/DiagnosticsSettings.tsx+6-3
...@@ -172,10 +172,11 @@ function DiagnosticsTable({...@@ -172,10 +172,11 @@ function DiagnosticsTable({
172}) {172}) {
173 return (173 return (
174 <ScrollArea174 <ScrollArea
175 radius="none"
175 chainVerticalScroll176 chainVerticalScroll
176 scrollFade177 scrollFade
177 hideScrollbars178 hideScrollbars
178 className="w-full max-w-full rounded-none"179 className="w-full max-w-full"
179 >180 >
180 <table181 <table
181 className={cn("w-full text-left text-xs", minTableWidth, columnWidths && "table-fixed")}182 className={cn("w-full text-left text-xs", minTableWidth, columnWidths && "table-fixed")}
...@@ -355,10 +356,11 @@ function ProcessDiagnosticsTable({...@@ -355,10 +356,11 @@ function ProcessDiagnosticsTable({
355356
356 return (357 return (
357 <ScrollArea358 <ScrollArea
359 radius="none"
358 chainVerticalScroll360 chainVerticalScroll
359 scrollFade361 scrollFade
360 hideScrollbars362 hideScrollbars
361 className="max-h-[min(64vh,44rem)] w-full max-w-full rounded-none border-t border-border/60"363 className="max-h-[min(64vh,44rem)] w-full max-w-full border-t border-border/60"
362 >364 >
363 <table className="w-full min-w-[1040px] table-fixed text-left text-xs">365 <table className="w-full min-w-[1040px] table-fixed text-left text-xs">
364 <colgroup>366 <colgroup>
...@@ -1224,10 +1226,11 @@ export function DiagnosticsSettingsPanel() {...@@ -1224,10 +1226,11 @@ export function DiagnosticsSettingsPanel() {
1224 <SettingsSection title="Span Logs">1226 <SettingsSection title="Span Logs">
1225 {data && data.latestWarningAndErrorLogs.length > 0 ? (1227 {data && data.latestWarningAndErrorLogs.length > 0 ? (
1226 <ScrollArea1228 <ScrollArea
1229 radius="none"
1227 chainVerticalScroll1230 chainVerticalScroll
1228 scrollFade1231 scrollFade
1229 hideScrollbars1232 hideScrollbars
1230 className="w-full max-w-full rounded-none"1233 className="w-full max-w-full"
1231 >1234 >
1232 <table className="w-full min-w-[920px] table-fixed text-left text-xs">1235 <table className="w-full min-w-[920px] table-fixed text-left text-xs">
1233 <colgroup>1236 <colgroup>
apps/web/src/components/settings/ProviderSettingsPanel.tsx+1-1
...@@ -334,7 +334,7 @@ function ProviderSettingsPanelContent(target: ProviderSettingsTarget) {...@@ -334,7 +334,7 @@ function ProviderSettingsPanelContent(target: ProviderSettingsTarget) {
334 options.length === 1 && options[0]?.entry.target._tag === "PrimaryConnectionTarget";334 options.length === 1 && options[0]?.entry.target._tag === "PrimaryConnectionTarget";
335 const deviceTabs =335 const deviceTabs =
336 !target.scoped && !onlyPrimaryDevice && options.length > 0 ? (336 !target.scoped && !onlyPrimaryDevice && options.length > 0 ? (
337 <ScrollArea hideScrollbars scrollFade className="h-11 min-w-0 flex-1 rounded-none">337 <ScrollArea radius="none" hideScrollbars scrollFade className="h-11 min-w-0 flex-1">
338 <ToggleGroup338 <ToggleGroup
339 aria-label="Devices"339 aria-label="Devices"
340 variant="segmented"340 variant="segmented"
apps/web/src/components/ui/scroll-area.tsx+8-1
...@@ -29,6 +29,7 @@ function ScrollArea({...@@ -29,6 +29,7 @@ function ScrollArea({
29 scrollbarGutter = false,29 scrollbarGutter = false,
30 hideScrollbars = false,30 hideScrollbars = false,
31 chainVerticalScroll = false,31 chainVerticalScroll = false,
32 radius = "inherit",
32 ...props33 ...props
33}: ScrollAreaPrimitive.Root.Props & {34}: ScrollAreaPrimitive.Root.Props & {
34 scrollFade?: boolean;35 scrollFade?: boolean;
...@@ -38,10 +39,16 @@ function ScrollArea({...@@ -38,10 +39,16 @@ function ScrollArea({
38 scrollbarGutter?: boolean;39 scrollbarGutter?: boolean;
39 hideScrollbars?: boolean;40 hideScrollbars?: boolean;
40 chainVerticalScroll?: boolean;41 chainVerticalScroll?: boolean;
42 /** The viewport clips to the parent's radius; "none" for a region flush to an edge. */
43 radius?: "inherit" | "none";
41}) {44}) {
42 return (45 return (
43 <ScrollAreaPrimitive.Root46 <ScrollAreaPrimitive.Root
44 className={cn("relative size-full min-h-0 overflow-hidden rounded-[inherit]", className)}47 className={cn(
48 "relative size-full min-h-0 overflow-hidden",
49 radius === "none" ? "rounded-none" : "rounded-[inherit]",
50 className,
51 )}
45 {...props}52 {...props}
46 >53 >
47 <ScrollAreaPrimitive.Viewport54 <ScrollAreaPrimitive.Viewport
scripts/lint-restyle-ceiling.ts+1-1
...@@ -8,7 +8,7 @@ import * as NodeURL from "node:url";...@@ -8,7 +8,7 @@ import * as NodeURL from "node:url";
8// components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the8// components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the
9// count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you9// count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you
10// migrate a file, and delete this script when the rule becomes an error.10// migrate a file, and delete this script when the rule becomes an error.
11export const RESTYLE_CEILING = 1070;11export const RESTYLE_CEILING = 1060;
1212
13const RULE = "shadcn(no-restyle)";13const RULE = "shadcn(no-restyle)";
1414