@@ -24,7 +24,7 @@ import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2"
2424
2525import { LayoutRoute , useLayout } from "@/context/layout"
2626import { usePlatform } from "@/context/platform"
27- import { useCommand } from "@/context/command"
27+ import { formatKeybindKeys , useCommand } from "@/context/command"
2828import { useLanguage } from "@/context/language"
2929import { useSettings } from "@/context/settings"
3030import { WindowsAppMenu } from "./windows-app-menu"
@@ -236,6 +236,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
236236
237237 return (
238238 < header
239+ data-slot = { useV2Titlebar ( ) ? "titlebar-v2" : undefined }
239240 classList = { {
240241 "shrink-0 relative flex flex-row" : true ,
241242 "h-9 bg-v2-background-bg-deep overflow-visible" : useV2Titlebar ( ) ,
@@ -351,6 +352,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
351352 tabs . newDraft ( { server : fallback . server , directory : fallback . project . worktree } , "" )
352353 }
353354 const toggleHome = ( ) => tabs . toggleHome ( { home : layout . route ( ) . type === "home" , current : currentTab ( ) } )
355+ const newTabKeybind = "mod+t"
354356
355357 command . register ( "titlebar-home" , ( ) => [
356358 {
@@ -371,7 +373,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
371373 id : "tab.new" ,
372374 category : "tab" ,
373375 title : language . t ( "command.session.new" ) ,
374- keybind : "mod+t" ,
376+ keybind : newTabKeybind ,
375377 hidden : true ,
376378 onSelect : openNewTab ,
377379 } ,
@@ -604,15 +606,25 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
604606 />
605607 </ div >
606608 < Show when = { ! ( creating ( ) && params . dir ) } >
607- < IconButtonV2
608- type = "button"
609- variant = "ghost-muted"
610- size = "large"
611- class = "shrink-0"
612- icon = { < IconV2 name = "plus" /> }
613- onClick = { openNewTab }
614- aria-label = { language . t ( "command.session.new" ) }
615- />
609+ < TooltipV2
610+ placement = "bottom"
611+ value = {
612+ < >
613+ { language . t ( "command.session.new" ) }
614+ < KeybindV2 keys = { formatKeybindKeys ( newTabKeybind , language . t ) } variant = "neutral" />
615+ </ >
616+ }
617+ >
618+ < IconButtonV2
619+ type = "button"
620+ variant = "ghost-muted"
621+ size = "large"
622+ class = "shrink-0"
623+ icon = { < IconV2 name = "plus" /> }
624+ onClick = { openNewTab }
625+ aria-label = { language . t ( "command.session.new" ) }
626+ />
627+ </ TooltipV2 >
616628 </ Show >
617629 < div class = "flex-1" />
618630 < TitlebarV2Right state = { v2RightState ( ) } />
@@ -808,16 +820,16 @@ function TitlebarV2Right(props: { state: TitlebarV2RightState }) {
808820
809821function TitlebarUpdateIconButton ( props : { state : TitlebarUpdatePillState } ) {
810822 return (
811- < div class = "relative isolate mr-3 size -5 shrink-0" >
823+ < div class = "group relative mr-3 h -5 w-5 shrink-0 rounded-full bg-v2-background-bg-deep transition-[width] duration-150 ease-out hover:z-30 hover:w-[68px] focus-within:z-30 focus-within:w-[68px] motion-reduce:transition-none " >
812824 < button
813825 type = "button"
814- class = "group absolute right-0 top-0 z-10 flex h-5 w-5 items-center justify-end overflow-hidden rounded-full bg-v2-icon-icon-accent/20 text-v2-icon-icon-accent transition-[width,background-color] duration-150 ease-out hover:z-30 hover:w-[68px] hover:bg-[color-mix(in_srgb,var(--v2-icon-icon-accent)_20%,var(--v2-background-bg-deep))] focus-visible:z-30 focus-visible :w-[68px] focus-visible :bg-[color-mix(in_srgb,var(--v2-icon-icon-accent)_20%,var(--v2-background-bg-deep))] focus-visible:outline-none disabled:opacity-60 motion-reduce:transition-none"
826+ class = "absolute right-0 top-0 z-10 flex h-5 w-5 items-center justify-end overflow-hidden rounded-full bg-v2-icon-icon-accent/20 text-v2-icon-icon-accent transition-[width,background-color] duration-150 ease-out group- hover:w-[68px] group- hover:bg-[color-mix(in_srgb,var(--v2-icon-icon-accent)_20%,var(--v2-background-bg-deep))] group- focus-within :w-[68px] group- focus-within :bg-[color-mix(in_srgb,var(--v2-icon-icon-accent)_20%,var(--v2-background-bg-deep))] focus-visible:outline-none disabled:opacity-60 motion-reduce:transition-none"
815827 onClick = { props . state . onInstall }
816828 disabled = { props . state . installing }
817829 aria-busy = { props . state . installing }
818830 aria-label = { props . state . ariaLabel }
819831 >
820- < span class = "shrink-0 ml-[8px] mr-px text-[11px] text-v2-text-text-accent [font-weight:530] opacity-0 translate-x-2 motion-safe:transition-all duration-150 ease-out group-hover:opacity-100 group-hover:translate-x-0 group-focus-visible :opacity-100 group-focus-visible :translate-x-0 motion-reduce:translate-x-0" >
832+ < span class = "shrink-0 ml-[8px] mr-px text-[11px] text-v2-text-text-accent [font-weight:530] opacity-0 translate-x-2 motion-safe:transition-all duration-150 ease-out group-hover:opacity-100 group-hover:translate-x-0 group-focus-within :opacity-100 group-focus-within :translate-x-0 motion-reduce:translate-x-0" >
821833 Update
822834 </ span >
823835 < span class = "flex size-5 shrink-0 items-center justify-center" >
@@ -863,7 +875,8 @@ function TabNavItem(props: {
863875 return (
864876 < div
865877 ref = { props . ref }
866- class = "group relative flex h-7 min-w-24 max-w-60 flex-row items-center gap-1.5 overflow-hidden whitespace-nowrap rounded-[6px] bg-[var(--tab-bg)] px-1.5 [--tab-bg:var(--v2-background-bg-deep)] hover:[--tab-bg:var(--v2-background-bg-layer-02)] data-[active='true']:[--tab-bg:var(--v2-background-bg-layer-02)]"
878+ data-slot = "titlebar-tab-item"
879+ class = "group relative flex h-7 min-w-24 max-w-60 flex-row items-center gap-1.5 overflow-hidden whitespace-nowrap rounded-[6px] bg-[var(--tab-bg)] px-1.5 [--tab-bg:var(--v2-background-bg-deep)] hover:[--tab-bg:var(--v2-background-bg-layer-02)] has-[>a:focus-visible]:[--tab-bg:var(--v2-background-bg-layer-02)] data-[active='true']:[--tab-bg:var(--v2-background-bg-layer-02)]"
867880 data-active = { props . active }
868881 onMouseDown = { ( event ) => {
869882 if ( event . button !== 1 ) return
@@ -898,10 +911,12 @@ function TabNavItem(props: {
898911 </ Show >
899912
900913 < div
914+ data-slot = "titlebar-tab-close"
901915 class = "absolute not-group-hover:not-group-data-[active=true]:not-data-[truncate=true]:left-52 group-hover:right-0 group-data-[active=true]:right-0 data-[truncate=true]:right-0 inset-y-0 flex flex-row items-center pr-1 py-1 w-8 pl-2"
902916 data-truncate = { props . forceTruncate }
903917 >
904918 < div
919+ data-slot = "titlebar-tab-close-fade"
905920 class = "absolute inset-0 rounded-r-[6px] bg-(image:--inactive-bg) group-hover:bg-(image:--active-bg) group-data-[active=true]:bg-(image:--active-bg)"
906921 style = { {
907922 "--inactive-bg" : "linear-gradient(to right, transparent 0%, var(--tab-bg) 80%)" ,
@@ -936,8 +951,9 @@ function DraftTabItem(props: {
936951 return (
937952 < div
938953 ref = { props . ref }
954+ data-slot = "titlebar-tab-item"
939955 data-active = { props . active }
940- class = "group relative shrink-0 flex h-7 max-w-60 flex-row items-center gap-1.5 overflow-hidden rounded-[6px] bg-[var(--tab-bg)] pl-1.5 pr-8 whitespace-nowrap [--tab-bg:var(--v2-background-bg-deep)] hover:[--tab-bg:var(--v2-background-bg-layer-02)] data-[active='true' ]:[--tab-bg:var(--v2-overlay-simple-overlay-pressed )] focus-within:outline focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-[ var(--v2-border-border-focus )]"
956+ class = "group relative shrink-0 flex h-7 max-w-60 flex-row items-center gap-1.5 overflow-hidden rounded-[6px] bg-[var(--tab-bg)] pl-1.5 pr-8 whitespace-nowrap [--tab-bg:var(--v2-background-bg-deep)] hover:[--tab-bg:var(--v2-background-bg-layer-02)] has-[>a:focus-visible ]:[--tab-bg:var(--v2-background-bg-layer-02 )] data-[active='true']:has-[>a: focus-visible]:[--tab-bg:var(--v2-background-bg-layer-02)] data-[active='true']:[--tab-bg: var(--v2-overlay-simple-overlay-pressed )]"
941957 onMouseDown = { ( event ) => {
942958 if ( event . button !== 1 ) return
943959 closeTab ( event )
@@ -982,7 +998,8 @@ function NewSessionTabItem(props: { ref?: HTMLDivElement; href: string; title: s
982998 return (
983999 < div
9841000 ref = { props . ref }
985- class = "group relative shrink-0 flex h-7 max-w-60 flex-row items-center gap-1.5 overflow-hidden rounded-[6px] bg-[var(--v2-overlay-simple-overlay-pressed)] pl-1.5 pr-8 whitespace-nowrap focus-within:outline focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-[var(--v2-border-border-focus)]"
1001+ data-slot = "titlebar-tab-item"
1002+ class = "group relative shrink-0 flex h-7 max-w-60 flex-row items-center gap-1.5 overflow-hidden rounded-[6px] bg-[var(--v2-overlay-simple-overlay-pressed)] has-[>a:focus-visible]:bg-[var(--v2-background-bg-layer-02)] pl-1.5 pr-8 whitespace-nowrap"
9861003 onMouseDown = { ( event ) => {
9871004 if ( event . button !== 1 ) return
9881005 closeTab ( event )
0 commit comments