Skip to content

Commit 16bc184

Browse files
refactor(web): ui components drop their secondary className props
Several components/ui exports took a second className for an inner part (viewportClassName, popupClassName, inputClassName, contentClassName, backdropClassName, wrapperClassName). Each was a restyle hatch the lint rule could not see. - Popover: padding="default" | "compact" | "none" names the three insets callers actually wanted (dense lists and excerpts, and content that draws its own frame). None rounds the viewport so edge-to-edge content clips to the popup's corners. - Sheet: sheets sit at a fixed tier (46), under the floating preview player (47-49) and under dialogs (50), so the right-panel sheet no longer needs a flag to drop below the player. - Dialog: the media variant owns its own layering and centering. - ComboboxItem content always lays out as one row: a truncating label, then trailing meta. Every consumer already had that shape. - The model picker search uses ComboboxSearchInput like the branch picker, which deletes inputClassName. - The sidebar snooze list is a Menu with MenuItem and MenuShortcut instead of hand-built buttons in a popover. - An input addon that holds a button takes clicks, so the command palette's back arrow no longer needs wrapperClassName. - Select popupClassName had no callers. no-restyle findings: 604 -> 583. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent c5cdcb6 commit 16bc184

30 files changed

Lines changed: 127 additions & 205 deletions

‎apps/web/src/components/ChatView.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10378,7 +10378,6 @@ export default function ChatView(props: ChatViewProps) {
1037810378
<RightPanelSheet
1037910379
animationDurationMs={panelAnimationsActive ? panelAnimationDurationMs : 0}
1038010380
open={rightPanelOpen}
10381-
underFloatingPreview={previewMiniPlayerVisible}
1038210381
onClose={closePreviewPanel}
1038310382
>
1038410383
<RightPanelTabs

‎apps/web/src/components/CommandPalette.tsx‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2966,9 +2966,6 @@ function OpenCommandPaletteDialog(props: {
29662966
})
29672967
: undefined,
29682968
placeholder: inputPlaceholder,
2969-
wrapperClassName: isSubmenu
2970-
? "[&_[data-slot=autocomplete-start-addon]]:pointer-events-auto"
2971-
: undefined,
29722969
...(isSubmenu
29732970
? {
29742971
startAddon: (

‎apps/web/src/components/DiffPanel.tsx‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,6 @@ export default function DiffPanel({
775775
<ComboboxList className="max-h-64 min-w-0 overflow-x-hidden">
776776
<ComboboxItem
777777
className="w-full min-w-0 grid-cols-[1rem_minmax(0,1fr)]"
778-
contentClassName="w-full min-w-0 overflow-hidden"
779778
value={AUTOMATIC_BASE_REF}
780779
>
781780
<span className="block min-w-0 truncate">Automatic</span>
@@ -788,7 +787,6 @@ export default function DiffPanel({
788787
<ComboboxItem
789788
key={choice.id}
790789
className="w-full min-w-0 grid-cols-[1rem_minmax(0,1fr)]"
791-
contentClassName="w-full min-w-0 overflow-hidden"
792790
value={item}
793791
>
794792
<div className="grid w-full min-w-0 grid-cols-[minmax(0,1fr)_2rem] items-center overflow-hidden">

‎apps/web/src/components/RightPanelSheet.tsx‎

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
import { type ReactNode } from "react";
22

3-
import {
4-
RIGHT_PANEL_SHEET_CLASS_NAME,
5-
RIGHT_PANEL_SHEET_LAYER_CLASS_NAME,
6-
} from "../rightPanelLayout";
3+
import { RIGHT_PANEL_SHEET_CLASS_NAME } from "../rightPanelLayout";
74
import { Sheet, SheetPopup } from "./ui/sheet";
85

96
export function RightPanelSheet(props: {
107
animationDurationMs: number;
118
children: ReactNode;
129
open: boolean;
13-
underFloatingPreview?: boolean;
1410
onClose: () => void;
1511
}) {
1612
return (
@@ -27,12 +23,6 @@ export function RightPanelSheet(props: {
2723
side="right"
2824
showCloseButton={false}
2925
keepMounted
30-
{...(props.underFloatingPreview
31-
? {
32-
backdropClassName: RIGHT_PANEL_SHEET_LAYER_CLASS_NAME,
33-
viewportClassName: RIGHT_PANEL_SHEET_LAYER_CLASS_NAME,
34-
}
35-
: {})}
3626
className={RIGHT_PANEL_SHEET_CLASS_NAME}
3727
>
3828
{props.children}

‎apps/web/src/components/Sidebar.tsx‎

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ import {
235235
import { SidebarContent, SidebarGroup, useSidebar } from "./ui/sidebar";
236236
import { SidebarChromeFooter, SidebarChromeHeader } from "./sidebar/SidebarChrome";
237237
import { SidebarHeaderIconButton, SidebarThreadHeader } from "./sidebar/SidebarThreadHeader";
238-
import { Popover, PopoverPopup, PopoverTrigger } from "./ui/popover";
238+
import { Menu, MenuItem, MenuPopup, MenuSeparator, MenuShortcut, MenuTrigger } from "./ui/menu";
239239
import { Tooltip, TooltipPopup, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
240240
import { MiddleTruncate } from "./ui/middle-truncate";
241241
import {
@@ -440,7 +440,7 @@ function SidebarThreadTooltip({
440440
* Controlled by the row (which also uses the open state to pin its hover
441441
* actions while the menu is up).
442442
*/
443-
function SnoozePopoverButton(props: {
443+
function SnoozeMenuButton(props: {
444444
open: boolean;
445445
onOpenChange: (open: boolean) => void;
446446
onSnooze: (preset: Pick<SnoozePreset, "snoozedUntil">) => void;
@@ -454,11 +454,11 @@ function SnoozePopoverButton(props: {
454454
[open, timestampFormat],
455455
);
456456
return (
457-
<Popover open={open} onOpenChange={onOpenChange}>
457+
<Menu open={open} onOpenChange={onOpenChange}>
458458
<Tooltip>
459459
<TooltipTrigger
460460
render={
461-
<PopoverTrigger
461+
<MenuTrigger
462462
render={
463463
<button
464464
type="button"
@@ -475,39 +475,31 @@ function SnoozePopoverButton(props: {
475475
</TooltipTrigger>
476476
<TooltipPopup>Snooze thread</TooltipPopup>
477477
</Tooltip>
478-
<PopoverPopup side="bottom" align="end" width="sm" viewportClassName="p-1">
478+
<MenuPopup side="bottom" align="end">
479479
{presets.map((preset) => (
480-
<button
480+
<MenuItem
481481
key={preset.id}
482-
type="button"
483482
onClick={(event) => {
484483
event.stopPropagation();
485-
onOpenChange(false);
486484
onSnooze(preset);
487485
}}
488-
className="flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs text-foreground/90 hover:bg-accent hover:text-foreground"
489486
>
490-
<span className="flex-1">{preset.label}</span>
491-
<span className="font-mono text-[10px] text-muted-foreground/60 tabular-nums">
492-
{preset.whenLabel}
493-
</span>
494-
</button>
487+
{preset.label}
488+
<MenuShortcut>{preset.whenLabel}</MenuShortcut>
489+
</MenuItem>
495490
))}
496-
<div className="my-1 border-t border-border/60" />
497-
<button
498-
type="button"
499-
className="flex w-full cursor-pointer rounded-md px-2 py-1.5 text-left text-xs text-foreground/90 hover:bg-accent hover:text-foreground"
491+
<MenuSeparator />
492+
<MenuItem
500493
onClick={async (event) => {
501494
event.stopPropagation();
502-
onOpenChange(false);
503495
const choice = await requestCustomSnooze();
504496
if (choice) onSnooze(choice);
505497
}}
506498
>
507499
Custom…
508-
</button>
509-
</PopoverPopup>
510-
</Popover>
500+
</MenuItem>
501+
</MenuPopup>
502+
</Menu>
511503
);
512504
}
513505

@@ -1883,7 +1875,7 @@ const SidebarThreadRow = memo(function SidebarThreadRow(props: {
18831875
</Tooltip>
18841876
) : null}
18851877
{showSnoozeButton ? (
1886-
<SnoozePopoverButton
1878+
<SnoozeMenuButton
18871879
open={snoozeMenuOpen}
18881880
onOpenChange={setSnoozeMenuOpen}
18891881
onSnooze={handleSnoozePreset}
@@ -4492,7 +4484,6 @@ export default function Sidebar() {
44924484
hideIndicator
44934485
value={item}
44944486
className="font-medium"
4495-
contentClassName="flex min-w-0 items-center gap-2"
44964487
onContextMenu={(event) => {
44974488
if (project) handleProjectSettings(event, project);
44984489
}}

‎apps/web/src/components/chat/AssistantCitationChip.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export function AssistantCitationChip({
171171
}}
172172
aria-label="Edit citation comment"
173173
width="md"
174-
viewportClassName="p-3"
174+
padding="compact"
175175
onPointerDown={(event) => event.stopPropagation()}
176176
>
177177
<AssistantCitationCommentEditor

‎apps/web/src/components/chat/ContextWindowMeter.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export function ContextWindowMeter(props: {
8888
tooltipStyle
8989
side="top"
9090
align="end"
91-
viewportClassName="p-0"
91+
padding="none"
9292
width="sm"
9393
className="text-left whitespace-normal"
9494
>

‎apps/web/src/components/chat/ExpandedImageDialog.tsx‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,6 @@ export const ExpandedImageDialog = memo(function ExpandedImageDialog({
179179
variant="media"
180180
showCloseButton={false}
181181
bottomStickOnMobile={false}
182-
backdropClassName="z-[60]"
183-
viewportClassName="z-[60] grid-rows-1 place-items-center px-4 py-6 [-webkit-app-region:no-drag]"
184182
className="row-start-1 max-h-[92vh] w-[92vw] max-w-[92vw] items-center overflow-visible [--media-width:92vw] [--media-height:min(86vh,calc(100vh-160px))] sm:[--media-width:calc(92vw-96px)]"
185183
onKeyDown={onKeyDown}
186184
initialFocus={closeButtonRef}

‎apps/web/src/components/chat/MessagesTimeline.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2567,7 +2567,7 @@ function BackgroundWorktreeSetupChip({ snapshot }: { snapshot: WorktreeSetupSnap
25672567
align="end"
25682568
width="lg"
25692569
className="surface-glass!"
2570-
viewportClassName="py-3 [--viewport-inline-padding:--spacing(3)]"
2570+
padding="compact"
25712571
>
25722572
<WorktreeSetupCard
25732573
snapshot={snapshot}

‎apps/web/src/components/chat/ModelListRow.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ export const ModelListRow = memo(function ModelListRow(props: {
5252
index={props.index}
5353
value={modelPickerModelKey(props.instanceId, props.model.slug)}
5454
disabled={Boolean(props.disabledReason)}
55-
contentClassName="flex w-full items-center gap-3"
5655
className={cn(
5756
"group relative w-full !min-w-0 max-w-full cursor-pointer rounded-md px-2 py-2 transition-[background-color,box-shadow,color]",
5857
"hover:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))] data-highlighted:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))] data-selected:bg-foreground/[0.08] data-selected:text-foreground data-selected:ring-0 [&[data-highlighted][data-selected]]:bg-[color-mix(in_srgb,var(--popover)_90%,var(--contrast-foreground))]",

0 commit comments

Comments
 (0)