mirror of
https://github.com/unslothai/unsloth.git
synced 2026-07-09 15:58:41 +00:00
Studio: rounded rectangle hover states for menu items instead of pills (#6210)
* Studio: use rounded rectangles for menu item hover states instead of pills Dropdown, select, and model picker items previously used fully rounded pill highlights. Switch them to an 11px rounded rectangle so hover and selected states match across the plus menu, profile menu, run settings, selects, and the model picker. Also add a small side gutter to the plus menu so item highlights sit slightly inset from the menu edge. * Studio: concentric menu corners, wider gutters, single-item pill menus Container radius now equals the item hover radius plus the side gutter (12px + 10px = 22px) so the curves run parallel. Menus with a single item render as fully rounded pills. The profile menu gets the same gutter and hover radius. Model picker rows go back to their original fully rounded hover.
This commit is contained in:
parent
e0d6674ff6
commit
068b2c120f
4 changed files with 34 additions and 18 deletions
|
|
@ -1099,7 +1099,7 @@ export function AppSidebar() {
|
|||
side="top"
|
||||
align="center"
|
||||
sideOffset={8}
|
||||
className="app-user-menu menu-soft-surface-up ring-0 w-[16rem] px-1.5 py-2.5 font-heading rounded-[20px] border-0"
|
||||
className="app-user-menu menu-soft-surface-up ring-0 w-[16rem] px-2.5 py-2.5 font-heading rounded-[20px] border-0"
|
||||
>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ function DropdownMenuItem({
|
|||
data-inset={inset}
|
||||
data-variant={variant}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-full px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-[11px] px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 group/dropdown-menu-item relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -99,7 +99,7 @@ function DropdownMenuCheckboxItem({
|
|||
<DropdownMenuPrimitive.CheckboxItem
|
||||
data-slot="dropdown-menu-checkbox-item"
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2.5 rounded-full py-2 pr-8 pl-3 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2.5 rounded-[11px] py-2 pr-8 pl-3 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
checked={checked}
|
||||
|
|
@ -138,7 +138,7 @@ function DropdownMenuRadioItem({
|
|||
<DropdownMenuPrimitive.RadioItem
|
||||
data-slot="dropdown-menu-radio-item"
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2.5 rounded-full py-2 pr-8 pl-3 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-2.5 rounded-[11px] py-2 pr-8 pl-3 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
@ -224,7 +224,7 @@ function DropdownMenuSubTrigger({
|
|||
data-slot="dropdown-menu-sub-trigger"
|
||||
data-inset={inset}
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-full px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2 rounded-[11px] px-3 py-2 text-sm [&_svg:not([class*='size-'])]:size-4 flex cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 data-[inset]:pl-8 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -173,7 +173,7 @@ function SelectItem({
|
|||
<SelectPrimitive.Item
|
||||
data-slot="select-item"
|
||||
className={cn(
|
||||
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-full py-2 pr-8 pl-3 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
"focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground gap-2.5 rounded-[11px] py-2 pr-8 pl-3 text-sm [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2 relative flex w-full cursor-pointer items-center outline-hidden select-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -779,7 +779,7 @@
|
|||
height: 36px;
|
||||
padding: 0 0.75rem !important;
|
||||
gap: 9.5px !important;
|
||||
border-radius: 9999px;
|
||||
border-radius: 12px;
|
||||
font-weight: 500;
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
|
|
@ -1294,18 +1294,33 @@
|
|||
|
||||
/* Soft elevation; [data-slot] outranks the component ring-1, dropping the border. */
|
||||
.unsloth-plus-menu[data-slot] {
|
||||
/* Pin radius so dark matches light (rounded-lg resolves smaller in dark).
|
||||
/* Concentric with the item hover boxes, like Gemini: container radius =
|
||||
item radius (12px) + side gutter (10px), so the curves run parallel.
|
||||
!important beats the global 14px dropdown radius. */
|
||||
border-radius: 18px !important;
|
||||
border-radius: 22px !important;
|
||||
padding-top: 0.5rem;
|
||||
padding-bottom: 0.5rem;
|
||||
/* Side gutter so item hover boxes sit inset from the menu edge, like
|
||||
Gemini's menus (more breathing room than a hairline gutter). */
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
box-shadow: 0 2px 8px -2px rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
|
||||
/* MCP menu is wider (232px), so nudge the radius up so it reads as round as
|
||||
the narrower + menu (18 * 232/212 ~= 20px). */
|
||||
/* Width does not change the concentric radius; the MCP menu uses the same
|
||||
item radius + gutter, so it keeps the same container radius. */
|
||||
.unsloth-plus-menu.mcp-menu[data-slot] {
|
||||
border-radius: 20px !important;
|
||||
border-radius: 22px !important;
|
||||
}
|
||||
|
||||
/* One-line menus (a single item, e.g. "All saved prompts…" with nothing
|
||||
pinned, or a lone "Export as Markdown") read as fully rounded pills. */
|
||||
.unsloth-plus-menu[data-slot]:not(:has(> :nth-child(2))) {
|
||||
border-radius: 9999px !important;
|
||||
}
|
||||
.unsloth-plus-menu[data-slot]:not(:has(> :nth-child(2)))
|
||||
:is([data-slot="dropdown-menu-item"], [data-slot="dropdown-menu-sub-trigger"]) {
|
||||
border-radius: 9999px;
|
||||
}
|
||||
|
||||
.dark .unsloth-plus-menu[data-slot] {
|
||||
|
|
@ -1319,14 +1334,15 @@
|
|||
[data-slot="dropdown-menu-item"],
|
||||
[data-slot="dropdown-menu-sub-trigger"]
|
||||
) {
|
||||
@apply gap-3 pl-4 pr-3 py-2 text-[14px];
|
||||
@apply gap-3 pl-3 pr-3 py-2 text-[14px];
|
||||
cursor: pointer;
|
||||
/* Pin hover-box radius so dark matches light (same as the container). */
|
||||
border-radius: 1.1rem;
|
||||
/* Pin hover-box radius so dark matches light (container radius minus the
|
||||
side gutter keeps the curves concentric). */
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.unsloth-plus-menu [data-slot="dropdown-menu-label"] {
|
||||
@apply pl-4 pr-3 py-1.5 text-[12px];
|
||||
@apply pl-3 pr-3 py-1.5 text-[12px];
|
||||
}
|
||||
|
||||
/* Active (green) items keep their primary text and icon color on hover. */
|
||||
|
|
@ -1370,8 +1386,8 @@
|
|||
[data-slot="dropdown-menu-sub-trigger"]
|
||||
)
|
||||
svg {
|
||||
width: 1.05rem;
|
||||
height: 1.05rem;
|
||||
width: 1.15rem;
|
||||
height: 1.15rem;
|
||||
}
|
||||
|
||||
/* Destructive items keep red text and a red-tinted hover, not the grey one. */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue