a very good jj gui
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

style: add border radius to buttons and fix command dialog positioning

- Change button base style from rounded-none to rounded-sm
- Update RevisionGraph to use shadcn Button component with ghost variant
- Fix command dialog to use fixed top positioning (20%) so search input
stays in place when results shrink

+25 -24
+6 -5
apps/desktop/src/components/RevisionGraph.tsx
··· 1 1 import { memo, useCallback, useMemo } from "react"; 2 2 import { Badge } from "@/components/ui/badge"; 3 + import { Button } from "@/components/ui/button"; 3 4 import { ScrollArea } from "@/components/ui/scroll-area"; 4 5 import type { Revision } from "@/tauri-commands"; 5 6 ··· 307 308 const description = revision.description.split("\n")[0] || "(no description)"; 308 309 309 310 return ( 310 - <button 311 - type="button" 311 + <Button 312 + variant="ghost" 312 313 onClick={() => onSelect(revision.change_id)} 313 314 data-change-id={revision.change_id} 314 315 style={{ height: ROW_HEIGHT }} 315 - className={`w-full text-left px-2 flex items-center transition-colors animate-in fade-in slide-in-from-left-1 duration-150 focus:outline-none ${ 316 - isSelected ? "bg-accent text-accent-foreground" : "hover:bg-muted/50" 316 + className={`w-full justify-start text-left px-2 animate-in fade-in slide-in-from-left-1 duration-150 ${ 317 + isSelected ? "bg-accent text-accent-foreground" : "" 317 318 } ${revision.is_immutable ? "opacity-60" : ""}`} 318 319 > 319 320 <div className="flex-1 min-w-0"> ··· 333 334 </div> 334 335 <div className="text-sm truncate">{description}</div> 335 336 </div> 336 - </button> 337 + </Button> 337 338 ); 338 339 }); 339 340
+5 -5
apps/desktop/src/components/ui/button.tsx
··· 4 4 import { cn } from "@/lib/utils" 5 5 6 6 const buttonVariants = cva( 7 - "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-none border border-transparent bg-clip-padding text-xs font-medium focus-visible:ring-1 aria-invalid:ring-1 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", 7 + "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 rounded-sm border border-transparent bg-clip-padding text-xs font-medium focus-visible:ring-1 aria-invalid:ring-1 [&_svg:not([class*='size-'])]:size-4 inline-flex items-center justify-center whitespace-nowrap transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none shrink-0 [&_svg]:shrink-0 outline-none group/button select-none", 8 8 { 9 9 variants: { 10 10 variant: { ··· 17 17 }, 18 18 size: { 19 19 default: "h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2", 20 - xs: "h-6 gap-1 rounded-none px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", 21 - sm: "h-7 gap-1 rounded-none px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", 20 + xs: "h-6 gap-1 px-2 text-xs has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3", 21 + sm: "h-7 gap-1 px-2.5 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5", 22 22 lg: "h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3", 23 23 icon: "size-8", 24 - "icon-xs": "size-6 rounded-none [&_svg:not([class*='size-'])]:size-3", 25 - "icon-sm": "size-7 rounded-none", 24 + "icon-xs": "size-6 [&_svg:not([class*='size-'])]:size-3", 25 + "icon-sm": "size-7", 26 26 "icon-lg": "size-9", 27 27 }, 28 28 },
+14 -14
apps/desktop/src/components/ui/command.tsx
··· 12 12 DialogHeader, 13 13 DialogTitle, 14 14 } from "@/components/ui/dialog"; 15 - import { 16 - InputGroup, 17 - InputGroupAddon, 18 - } from "@/components/ui/input-group"; 15 + import { InputGroup, InputGroupAddon } from "@/components/ui/input-group"; 19 16 20 17 function Command({ 21 18 className, ··· 25 22 <CommandPrimitive 26 23 data-slot="command" 27 24 className={cn( 28 - "bg-popover text-popover-foreground rounded-none flex size-full flex-col overflow-hidden", 29 - className, 25 + "bg-popover text-popover-foreground rounded-sm flex size-full flex-col overflow-hidden", 26 + className 30 27 )} 31 28 {...props} 32 29 /> ··· 54 51 <DialogDescription>{description}</DialogDescription> 55 52 </DialogHeader> 56 53 <DialogContent 57 - className={cn("rounded-none overflow-hidden p-0", className)} 54 + className={cn("rounded-sm overflow-hidden p-0 top-[20%] translate-y-0", className)} 58 55 showCloseButton={showCloseButton} 59 56 > 60 57 <Command>{children}</Command> ··· 68 65 ...props 69 66 }: React.ComponentProps<typeof CommandPrimitive.Input>) { 70 67 return ( 71 - <div data-slot="command-input-wrapper" className="border-b pb-0"> 68 + <div 69 + data-slot="command-input-wrapper" 70 + className="border-b pb-0" 71 + > 72 72 <InputGroup className="bg-input/30 border-input/30 h-8 border-none shadow-none! *:data-[slot=input-group-addon]:pl-2!"> 73 73 <CommandPrimitive.Input 74 74 data-slot="command-input" 75 75 className={cn( 76 76 "w-full text-xs outline-hidden disabled:cursor-not-allowed disabled:opacity-50", 77 - className, 77 + className 78 78 )} 79 79 {...props} 80 80 /> ··· 95 95 data-slot="command-list" 96 96 className={cn( 97 97 "no-scrollbar max-h-72 scroll-py-0 outline-none overflow-x-hidden overflow-y-auto", 98 - className, 98 + className 99 99 )} 100 100 {...props} 101 101 /> ··· 124 124 data-slot="command-group" 125 125 className={cn( 126 126 "text-foreground [&_[cmdk-group-heading]]:text-muted-foreground overflow-hidden [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs", 127 - className, 127 + className 128 128 )} 129 129 {...props} 130 130 /> ··· 152 152 <CommandPrimitive.Item 153 153 data-slot="command-item" 154 154 className={cn( 155 - "data-selected:bg-muted data-selected:text-foreground data-selected:*:[svg]:text-foreground relative flex cursor-default items-center gap-2 rounded-none px-2 py-2 text-xs outline-hidden select-none [&_svg:not([class*='size-'])]:size-4 [[data-slot=dialog-content]_&]:rounded-none! group/command-item data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", 156 - className, 155 + "data-selected:bg-muted data-selected:text-foreground data-selected:*:[svg]:text-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-2 text-xs outline-hidden select-none [&_svg:not([class*='size-'])]:size-4 in-data-[slot=dialog-content]:rounded-sm! group/command-item data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0", 156 + className 157 157 )} 158 158 {...props} 159 159 /> ··· 169 169 data-slot="command-shortcut" 170 170 className={cn( 171 171 "text-muted-foreground group-data-selected/command-item:text-foreground ml-auto text-xs tracking-widest", 172 - className, 172 + className 173 173 )} 174 174 {...props} 175 175 />