authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-06-09 17:15:09-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-06-09 17:15:09-07:00
logb03bc4b52d184c5f2367d702e043586a0e9fcdaa
tree9cded4c0f735f3a617ca3a8fb34232a6c108a499
parentaca14507f729a1a8279cc77f8a94072d87e00e1b
signature Signed by PGP key B5690EEEBB952194

Mute icons in labeled controls and suppress popup focus rings (#3015)

Co-authored-by: ss <ss@barekey.dev> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

6 files changed, 23 insertions(+), 10 deletions(-)

apps/web/src/components/ui/autocomplete.tsx+1-1
...@@ -125,7 +125,7 @@ function AutocompleteItem({ className, children, ...props }: AutocompletePrimiti...@@ -125,7 +125,7 @@ function AutocompleteItem({ className, children, ...props }: AutocompletePrimiti
125 return (125 return (
126 <AutocompletePrimitive.Item126 <AutocompletePrimitive.Item
127 className={cn(127 className={cn(
128 "flex min-h-8 cursor-default select-none items-center rounded-sm px-2 py-1 text-base outline-none hover:bg-accent data-disabled:pointer-events-none data-selected:bg-accent/50 data-selected:text-foreground data-highlighted:bg-accent data-highlighted:text-accent-foreground [&[data-highlighted][data-selected]]:bg-accent [&[data-highlighted][data-selected]]:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm",128 "flex min-h-8 cursor-default select-none items-center rounded-sm px-2 py-1 text-base outline-none hover:bg-accent data-disabled:pointer-events-none data-selected:bg-accent/50 data-selected:text-foreground data-highlighted:bg-accent data-highlighted:text-accent-foreground [&[data-highlighted][data-selected]]:bg-accent [&[data-highlighted][data-selected]]:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&_svg:not([class*='text-'])]:text-muted-foreground",
129 className,129 className,
130 )}130 )}
131 data-slot="autocomplete-item"131 data-slot="autocomplete-item"
apps/web/src/components/ui/button.tsx+2-2
...@@ -37,10 +37,10 @@ const buttonVariants = cva(...@@ -37,10 +37,10 @@ const buttonVariants = cva(
37 "destructive-outline":37 "destructive-outline":
38 "border-input bg-popover not-dark:bg-clip-padding text-destructive-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:border-destructive/32 [:hover,[data-pressed]]:bg-destructive/4",38 "border-input bg-popover not-dark:bg-clip-padding text-destructive-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:border-destructive/32 [:hover,[data-pressed]]:bg-destructive/4",
39 ghost:39 ghost:
40 "border-transparent text-foreground data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent",40 "border-transparent text-foreground data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent [&_svg:not([class*='text-'])]:text-muted-foreground",
41 link: "border-transparent underline-offset-4 [:hover,[data-pressed]]:underline",41 link: "border-transparent underline-offset-4 [:hover,[data-pressed]]:underline",
42 outline:42 outline:
43 "border-input bg-popover not-dark:bg-clip-padding text-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-accent/50 dark:[:hover,[data-pressed]]:bg-input/64",43 "border-input bg-popover not-dark:bg-clip-padding text-foreground shadow-xs/5 not-disabled:not-active:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] dark:bg-input/32 dark:not-disabled:before:shadow-[0_-1px_--theme(--color-white/2%)] dark:not-disabled:not-active:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [:disabled,:active,[data-pressed]]:shadow-none [:hover,[data-pressed]]:bg-accent/50 dark:[:hover,[data-pressed]]:bg-input/64 [&_svg:not([class*='text-'])]:text-muted-foreground",
44 secondary:44 secondary:
45 "border-transparent bg-secondary text-secondary-foreground [:active,[data-pressed]]:bg-secondary/80 [:hover,[data-pressed]]:bg-secondary/90",45 "border-transparent bg-secondary text-secondary-foreground [:active,[data-pressed]]:bg-secondary/80 [:hover,[data-pressed]]:bg-secondary/90",
46 },46 },
apps/web/src/components/ui/combobox.tsx+2
...@@ -208,9 +208,11 @@ function ComboboxItem({...@@ -208,9 +208,11 @@ function ComboboxItem({
208 </ComboboxPrimitive.ItemIndicator>208 </ComboboxPrimitive.ItemIndicator>
209 <div209 <div
210 className={cn(210 className={cn(
211 "[&_svg:not([class*='text-'])]:text-muted-foreground",
211 hideIndicator ? "col-start-1 col-span-full" : "col-start-2",212 hideIndicator ? "col-start-1 col-span-full" : "col-start-2",
212 contentClassName,213 contentClassName,
213 )}214 )}
215 data-slot="combobox-item-content"
214 >216 >
215 {children}217 {children}
216 </div>218 </div>
apps/web/src/components/ui/menu.tsx+2-2
...@@ -78,7 +78,7 @@ function MenuItem({...@@ -78,7 +78,7 @@ function MenuItem({
78 return (78 return (
79 <MenuPrimitive.Item79 <MenuPrimitive.Item
80 className={cn(80 className={cn(
81 "[&>svg]:-mx-0.5 flex min-h-8 cursor-default select-none items-center gap-2 rounded-sm px-2 py-1 text-base text-foreground outline-none data-disabled:pointer-events-none data-highlighted:bg-accent data-inset:ps-8 data-[variant=destructive]:text-destructive-foreground data-highlighted:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&>svg:not([class*='opacity-'])]:opacity-80 [&>svg:not([class*='size-'])]:size-4.5 sm:[&>svg:not([class*='size-'])]:size-4 [&>svg]:pointer-events-none [&>svg]:shrink-0",81 "[&>svg]:-mx-0.5 flex min-h-8 cursor-default select-none items-center gap-2 rounded-sm px-2 py-1 text-base text-foreground outline-none data-disabled:pointer-events-none data-highlighted:bg-accent data-inset:ps-8 data-[variant=destructive]:text-destructive-foreground data-highlighted:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&>svg:not([class*='opacity-'])]:opacity-80 [&>svg:not([class*='size-'])]:size-4.5 sm:[&>svg:not([class*='size-'])]:size-4 [&>svg:not([class*='text-'])]:text-muted-foreground data-[variant=destructive]:[&>svg:not([class*='text-'])]:text-current [&>svg]:pointer-events-none [&>svg]:shrink-0",
82 className,82 className,
83 )}83 )}
84 data-inset={inset}84 data-inset={inset}
...@@ -235,7 +235,7 @@ function MenuSubTrigger({...@@ -235,7 +235,7 @@ function MenuSubTrigger({
235 return (235 return (
236 <MenuPrimitive.SubmenuTrigger236 <MenuPrimitive.SubmenuTrigger
237 className={cn(237 className={cn(
238 "flex min-h-8 items-center gap-2 rounded-sm px-2 py-1 text-base text-foreground outline-none data-disabled:pointer-events-none data-highlighted:bg-accent data-popup-open:bg-accent data-inset:ps-8 data-highlighted:text-accent-foreground data-popup-open:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none",238 "flex min-h-8 items-center gap-2 rounded-sm px-2 py-1 text-base text-foreground outline-none data-disabled:pointer-events-none data-highlighted:bg-accent data-popup-open:bg-accent data-inset:ps-8 data-highlighted:text-accent-foreground data-popup-open:text-accent-foreground data-disabled:opacity-64 sm:min-h-7 sm:text-sm [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none",
239 className,239 className,
240 )}240 )}
241 data-inset={inset}241 data-inset={inset}
apps/web/src/components/ui/select.tsx+8-5
...@@ -21,7 +21,7 @@ const selectTriggerVariants = cva(...@@ -21,7 +21,7 @@ const selectTriggerVariants = cva(
21 variants: {21 variants: {
22 variant: {22 variant: {
23 default:23 default:
24 "w-full min-w-36 border-input bg-background not-dark:bg-clip-padding text-foreground shadow-xs/5 ring-ring/24 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] not-data-disabled:not-focus-visible:not-aria-invalid:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 focus-visible:border-ring focus-visible:ring-[3px] aria-invalid:border-destructive/36 focus-visible:aria-invalid:border-destructive/64 focus-visible:aria-invalid:ring-destructive/16 dark:bg-input/32 dark:aria-invalid:ring-destructive/24 dark:not-data-disabled:not-focus-visible:not-aria-invalid:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [&_svg:not([class*='opacity-'])]:opacity-80 [[data-disabled],:focus-visible,[aria-invalid],[data-pressed]]:shadow-none",24 "w-full min-w-36 border-input bg-background not-dark:bg-clip-padding text-foreground shadow-xs/5 ring-ring/24 before:pointer-events-none before:absolute before:inset-0 before:rounded-[calc(var(--radius-lg)-1px)] not-data-disabled:not-focus-visible:not-aria-invalid:not-data-pressed:before:shadow-[0_1px_--theme(--color-black/4%)] pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 focus-visible:border-ring focus-visible:ring-[3px] aria-invalid:border-destructive/36 focus-visible:aria-invalid:border-destructive/64 focus-visible:aria-invalid:ring-destructive/16 dark:bg-input/32 dark:aria-invalid:ring-destructive/24 dark:not-data-disabled:not-focus-visible:not-aria-invalid:not-data-pressed:before:shadow-[0_-1px_--theme(--color-white/6%)] [&_svg:not([class*='opacity-'])]:opacity-80 [&_svg:not([class*='text-'])]:text-muted-foreground [[data-disabled],:focus-visible,[aria-invalid],[data-pressed]]:shadow-none",
25 ghost:25 ghost:
26 "border-transparent text-muted-foreground/70 focus-visible:ring-2 focus-visible:ring-ring data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent [:hover,[data-pressed]]:text-foreground/80",26 "border-transparent text-muted-foreground/70 focus-visible:ring-2 focus-visible:ring-ring data-pressed:bg-accent [:hover,[data-pressed]]:bg-accent [:hover,[data-pressed]]:text-foreground/80",
27 },27 },
...@@ -54,7 +54,7 @@ function SelectButton({ className, size, variant, render, children, ...props }:...@@ -54,7 +54,7 @@ function SelectButton({ className, size, variant, render, children, ...props }:
54 {children}54 {children}
55 </span>55 </span>
56 {variant === "ghost" ? (56 {variant === "ghost" ? (
57 <ChevronDownIcon className="size-3 opacity-50" />57 <ChevronDownIcon className="-me-1 size-3 opacity-50" />
58 ) : (58 ) : (
59 <ChevronsUpDownIcon className={selectTriggerIconClassName} />59 <ChevronsUpDownIcon className={selectTriggerIconClassName} />
60 )}60 )}
...@@ -87,7 +87,7 @@ function SelectTrigger({...@@ -87,7 +87,7 @@ function SelectTrigger({
87 >87 >
88 {children}88 {children}
89 <SelectPrimitive.Icon data-slot="select-icon">89 <SelectPrimitive.Icon data-slot="select-icon">
90 <ChevronDownIcon className="size-3 opacity-50" />90 <ChevronDownIcon className="-me-1 size-3 opacity-50" />
91 </SelectPrimitive.Icon>91 </SelectPrimitive.Icon>
92 </SelectPrimitive.Trigger>92 </SelectPrimitive.Trigger>
93 );93 );
...@@ -138,7 +138,7 @@ function SelectPopup({...@@ -138,7 +138,7 @@ function SelectPopup({
138 sideOffset={sideOffset}138 sideOffset={sideOffset}
139 >139 >
140 <SelectPrimitive.Popup140 <SelectPrimitive.Popup
141 className="origin-(--transform-origin) text-foreground"141 className="origin-(--transform-origin) rounded-lg text-foreground outline-none"
142 data-slot="select-popup"142 data-slot="select-popup"
143 {...props}143 {...props}
144 >144 >
...@@ -210,7 +210,10 @@ function SelectItem({...@@ -210,7 +210,10 @@ function SelectItem({
210 </SelectPrimitive.ItemIndicator>210 </SelectPrimitive.ItemIndicator>
211 )}211 )}
212 <SelectPrimitive.ItemText212 <SelectPrimitive.ItemText
213 className={cn("min-w-0", hideIndicator ? "col-start-1" : "col-start-2")}213 className={cn(
214 "min-w-0 [&_svg:not([class*='text-'])]:text-muted-foreground",
215 hideIndicator ? "col-start-1" : "col-start-2",
216 )}
214 data-slot="select-item-text"217 data-slot="select-item-text"
215 >218 >
216 {children}219 {children}
apps/web/src/index.css+8
...@@ -54,6 +54,14 @@...@@ -54,6 +54,14 @@
54 * {54 * {
55 @apply border-border outline-ring/50;55 @apply border-border outline-ring/50;
56 }56 }
57 :where([data-slot="menu-popup"], [data-slot="select-popup"], [data-slot="popover-popup"]):focus,
58 :where(
59 [data-slot="menu-popup"],
60 [data-slot="select-popup"],
61 [data-slot="popover-popup"]
62 ):focus-visible {
63 @apply outline-none ring-0;
64 }
57 html {65 html {
58 background-color: var(--app-chrome-background);66 background-color: var(--app-chrome-background);
59 }67 }