refactor(desktop): DRY/elegance pass over PR-touched files
- Shared useDeepLinkHighlight hook collapses 3 near-identical settings deep-link effects (keys/mcp); config kept inline (distinct bail-clear). - command-center: table-driven SECTION_ICONS + single errorText helper. - clarify-tool: OPTION_ROW_CLASS + RadioDot extracted from option rows. - desktop-controller: merge Cmd+K / Cmd+. into one keydown handler. - statusbar-controls: hoist shared action class. - Misc: drop redundant cn()/cursor-pointer/dead fields; tidy switch.
This commit is contained in:
parent
38acced687
commit
bc9e33d66b
13 changed files with 181 additions and 197 deletions
|
|
@ -33,6 +33,23 @@ function readClarifyArgs(args: unknown): ClarifyArgs {
|
|||
}
|
||||
}
|
||||
|
||||
// Choice and "Other" rows share a layout; only color/hover differs.
|
||||
const OPTION_ROW_CLASS = 'flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm transition-colors'
|
||||
|
||||
function RadioDot({ selected }: { selected: boolean }) {
|
||||
return (
|
||||
<span
|
||||
aria-hidden
|
||||
className={cn(
|
||||
'grid size-3.5 shrink-0 place-items-center rounded-full border transition-colors',
|
||||
selected ? 'border-primary' : 'border-muted-foreground/40'
|
||||
)}
|
||||
>
|
||||
{selected && <span className="size-1.5 rounded-full bg-primary" />}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export const ClarifyTool = (props: ToolCallMessagePartProps) => {
|
||||
const isPending = props.result === undefined
|
||||
|
||||
|
|
@ -164,8 +181,8 @@ function ClarifyToolPending({ args }: ToolCallMessagePartProps) {
|
|||
{choices.map((choice, index) => (
|
||||
<button
|
||||
className={cn(
|
||||
'flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm text-foreground/95',
|
||||
'transition-colors hover:bg-accent/60 disabled:cursor-not-allowed disabled:opacity-55',
|
||||
OPTION_ROW_CLASS,
|
||||
'text-foreground/95 hover:bg-accent/60 disabled:cursor-not-allowed disabled:opacity-55',
|
||||
selectedChoice === choice && 'bg-accent/60'
|
||||
)}
|
||||
data-choice
|
||||
|
|
@ -177,24 +194,13 @@ function ClarifyToolPending({ args }: ToolCallMessagePartProps) {
|
|||
}}
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-hidden
|
||||
className={cn(
|
||||
'grid size-3.5 shrink-0 place-items-center rounded-full border transition-colors',
|
||||
selectedChoice === choice ? 'border-primary' : 'border-muted-foreground/40'
|
||||
)}
|
||||
>
|
||||
{selectedChoice === choice && <span className="size-1.5 rounded-full bg-primary" />}
|
||||
</span>
|
||||
<RadioDot selected={selectedChoice === choice} />
|
||||
<span className="flex-1 wrap-anywhere">{choice}</span>
|
||||
{selectedChoice === choice && <Check aria-hidden className="size-4 shrink-0 text-primary" />}
|
||||
</button>
|
||||
))}
|
||||
<button
|
||||
className={cn(
|
||||
'flex w-full items-center gap-2 rounded-md px-2.5 py-1.5 text-left text-sm text-muted-foreground',
|
||||
'transition-colors hover:bg-accent/40 hover:text-foreground'
|
||||
)}
|
||||
className={cn(OPTION_ROW_CLASS, 'text-muted-foreground hover:bg-accent/40 hover:text-foreground')}
|
||||
disabled={submitting}
|
||||
onClick={() => {
|
||||
setTyping(true)
|
||||
|
|
@ -202,7 +208,7 @@ function ClarifyToolPending({ args }: ToolCallMessagePartProps) {
|
|||
}}
|
||||
type="button"
|
||||
>
|
||||
<span aria-hidden className="size-3.5 shrink-0 rounded-full border border-muted-foreground/40" />
|
||||
<RadioDot selected={false} />
|
||||
<span className="flex-1">Other (type your answer)</span>
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ function DropdownMenuItem({
|
|||
return (
|
||||
<DropdownMenuPrimitive.Item
|
||||
className={cn(
|
||||
"relative flex cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none focus:bg-(--ui-control-active-background) focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 [&_svg:not([class*='text-'])]:text-(--ui-text-tertiary) data-[variant=destructive]:*:[svg]:text-destructive!",
|
||||
"relative flex items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none focus:bg-(--ui-control-active-background) focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5 [&_svg:not([class*='text-'])]:text-(--ui-text-tertiary) data-[variant=destructive]:*:[svg]:text-destructive!",
|
||||
className
|
||||
)}
|
||||
data-inset={inset}
|
||||
|
|
@ -131,7 +131,7 @@ function DropdownMenuCheckboxItem({
|
|||
<DropdownMenuPrimitive.CheckboxItem
|
||||
checked={checked}
|
||||
className={cn(
|
||||
"relative flex cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none focus:bg-(--ui-control-active-background) focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"relative flex items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none focus:bg-(--ui-control-active-background) focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className
|
||||
)}
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
|
|
@ -157,7 +157,7 @@ function DropdownMenuRadioItem({
|
|||
return (
|
||||
<DropdownMenuPrimitive.RadioItem
|
||||
className={cn(
|
||||
"relative flex cursor-pointer items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none focus:bg-(--ui-control-active-background) focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
"relative flex items-center gap-2 rounded-md px-2 py-1 text-xs outline-hidden select-none focus:bg-(--ui-control-active-background) focus:text-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-3.5",
|
||||
className
|
||||
)}
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ function Switch({
|
|||
}: React.ComponentProps<typeof SwitchPrimitive.Root> & VariantProps<typeof switchVariants>) {
|
||||
return (
|
||||
<SwitchPrimitive.Root className={cn(switchVariants({ size }), className)} data-slot="switch" {...props}>
|
||||
<SwitchPrimitive.Thumb className={cn(switchThumbVariants({ size }))} data-slot="switch-thumb" />
|
||||
<SwitchPrimitive.Thumb className={switchThumbVariants({ size })} data-slot="switch-thumb" />
|
||||
</SwitchPrimitive.Root>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue