@@ -48,6 +48,7 @@ import { ICustomizationHarnessService } from '../../common/customizationHarnessS
4848import { ICommandService } from '../../../../../platform/commands/common/commands.js' ;
4949import { IAICustomizationListItem } from './aiCustomizationItemSource.js' ;
5050import { IAICustomizationItemsModel , ItemsModelSection } from './aiCustomizationItemsModel.js' ;
51+ import { createCustomizationCardPrimaryAction , CustomizationCardListController } from './customizationCardList.js' ;
5152
5253export { truncateToFirstLine } from './aiCustomizationListWidgetUtils.js' ;
5354
@@ -513,6 +514,10 @@ export function getAlwaysVisibleCustomizationGroupKeys(section: AICustomizationM
513514 : [ ] ;
514515}
515516
517+ export function getTargetedCreateActionLabel ( label : string , compactLabel ?: string ) : string {
518+ return compactLabel ?? label . replace ( / ^ \$ \( [ ^ ) ] + \) \s * / , '' ) ;
519+ }
520+
516521/**
517522 * Returns the ARIA status announcement string for a given section, item
518523 * count, and whether a search filter is active. Exported for testing.
@@ -573,6 +578,7 @@ export function getCountAnnouncement(section: AICustomizationManagementSection,
573578 */
574579interface ICreateAction {
575580 readonly label : string ;
581+ readonly compactLabel ?: string ;
576582 readonly enabled : boolean ;
577583 readonly tooltip ?: string ;
578584 readonly kind ?: 'generate' ;
@@ -1219,13 +1225,15 @@ export class AICustomizationListWidget extends Disposable {
12191225 if ( hasWorkspace ) {
12201226 actions . push ( {
12211227 label : localize ( 'newHook' , "New Hook" ) ,
1228+ compactLabel : localize ( 'newHook' , "New Hook" ) ,
12221229 enabled : true ,
12231230 target : 'workspace' ,
12241231 run : ( ) => { this . _onDidRequestCreateManual . fire ( { type : promptType , target : 'local' } ) ; } ,
12251232 } ) ;
12261233 }
12271234 actions . push ( {
12281235 label : localize ( 'newHook' , "New Hook" ) ,
1236+ compactLabel : localize ( 'newHook' , "New Hook" ) ,
12291237 enabled : true ,
12301238 target : 'user' ,
12311239 run : ( ) => { this . _onDidRequestCreateManual . fire ( { type : promptType , target : 'user' } ) ; } ,
@@ -1250,6 +1258,7 @@ export class AICustomizationListWidget extends Disposable {
12501258 // Sessions or non-local harness with workspace: workspace is primary
12511259 actions . push ( {
12521260 label : localize ( 'newWorkspaceCustomization' , "New {0} (Workspace)" , createTypeLabel ) ,
1261+ compactLabel : localize ( 'newCustomization' , "New {0}" , createTypeLabel ) ,
12531262 enabled : true ,
12541263 target : 'workspace' ,
12551264 run : ( ) => { this . _onDidRequestCreateManual . fire ( { type : promptType , target : 'local' } ) ; } ,
@@ -1259,6 +1268,7 @@ export class AICustomizationListWidget extends Disposable {
12591268 // No workspace: user is primary
12601269 actions . push ( {
12611270 label : localize ( 'newUserCustomization' , "New {0} (User)" , createTypeLabel ) ,
1271+ compactLabel : localize ( 'newCustomization' , "New {0}" , createTypeLabel ) ,
12621272 enabled : true ,
12631273 target : 'user' ,
12641274 run : ( ) => { this . _onDidRequestCreateManual . fire ( { type : promptType , target : 'user' } ) ; } ,
@@ -1271,6 +1281,7 @@ export class AICustomizationListWidget extends Disposable {
12711281 if ( hasWorkspace && ! addedTargets . has ( 'workspace' ) ) {
12721282 actions . push ( {
12731283 label : localize ( 'newWorkspaceCustomization' , "New {0} (Workspace)" , createTypeLabel ) ,
1284+ compactLabel : localize ( 'newCustomization' , "New {0}" , createTypeLabel ) ,
12741285 enabled : true ,
12751286 target : 'workspace' ,
12761287 run : ( ) => { this . _onDidRequestCreateManual . fire ( { type : promptType , target : 'local' } ) ; } ,
@@ -1280,6 +1291,7 @@ export class AICustomizationListWidget extends Disposable {
12801291 if ( ! addedTargets . has ( 'user' ) ) {
12811292 actions . push ( {
12821293 label : localize ( 'newUserCustomization' , "New {0} (User)" , createTypeLabel ) ,
1294+ compactLabel : localize ( 'newCustomization' , "New {0}" , createTypeLabel ) ,
12831295 enabled : true ,
12841296 target : 'user' ,
12851297 run : ( ) => { this . _onDidRequestCreateManual . fire ( { type : promptType , target : 'user' } ) ; } ,
@@ -1598,13 +1610,14 @@ export class AICustomizationListWidget extends Disposable {
15981610 }
15991611
16001612 const inventory = DOM . append ( section , $ ( '.plugin-card-grid.plugin-inventory-list.customization-inventory-list' ) ) ;
1613+ const cardList = this . cardDisposables . add ( new CustomizationCardListController ( inventory , group . label ) ) ;
16011614 if ( group . items . length === 0 ) {
16021615 const empty = DOM . append ( inventory , $ ( '.plugin-inventory-empty' ) ) ;
16031616 empty . textContent = this . getEmptyGroupMessage ( group . groupKey ) ;
16041617 continue ;
16051618 }
16061619 for ( const item of group . items ) {
1607- this . appendCustomizationCardRow ( inventory , item , group . label ) ;
1620+ this . appendCustomizationCardRow ( inventory , item , group . label , cardList ) ;
16081621 }
16091622 }
16101623 if ( shouldRestoreFocus ) {
@@ -1686,9 +1699,7 @@ export class AICustomizationListWidget extends Disposable {
16861699 }
16871700
16881701 private formatTargetedCreateActionLabel ( action : ICreateAction ) : string {
1689- return action . label
1690- . replace ( / ^ \$ \( [ ^ ) ] + \) \s * / , '' )
1691- . replace ( / \s + \( (?: W o r k s p a c e | U s e r ) \) $ / , '' ) ;
1702+ return getTargetedCreateActionLabel ( action . label , action . compactLabel ) ;
16921703 }
16931704
16941705 private showCreateActionsMenu ( createActions : readonly ICreateAction [ ] , anchor : HTMLElement ) : void {
@@ -1764,7 +1775,7 @@ export class AICustomizationListWidget extends Disposable {
17641775 this . cardDisposables . add ( button . onDidClick ( ( ) => this . executePrimaryCreateAction ( ) ) ) ;
17651776 }
17661777
1767- private appendCustomizationCardRow ( parent : HTMLElement , item : IAICustomizationListItem , groupLabel : string ) : void {
1778+ private appendCustomizationCardRow ( parent : HTMLElement , item : IAICustomizationListItem , groupLabel : string , cardList : CustomizationCardListController ) : void {
17681779 const row = DOM . append ( parent , $ ( '.plugin-list-item.plugin-home-row.customization-home-row' ) ) ;
17691780 row . classList . toggle ( 'disabled' , item . disabled ) ;
17701781 const displayName = item . displayName ?? formatDisplayName ( item . name ) ;
@@ -1774,10 +1785,7 @@ export class AICustomizationListWidget extends Disposable {
17741785 const accessibleLabel = item . disabled
17751786 ? localize ( 'customizationCardAriaLabelDisabled' , "{0}. {1}. Disabled" , displayName , accessibleSecondaryText || groupLabel )
17761787 : localize ( 'customizationCardAriaLabel' , "{0}. {1}" , displayName , accessibleSecondaryText || groupLabel ) ;
1777- const primary = DOM . append ( row , $ ( '.customization-row-primary' ) ) ;
1778- primary . tabIndex = 0 ;
1779- primary . setAttribute ( 'role' , 'button' ) ;
1780- primary . setAttribute ( 'aria-label' , accessibleLabel ) ;
1788+ const primary = createCustomizationCardPrimaryAction ( row , accessibleLabel , 'customization-row-primary' ) ;
17811789 this . firstCardFocusElement ??= primary ;
17821790 if ( ! this . cardRowsByUri . has ( item . uri . toString ( ) ) ) {
17831791 this . cardRowsByUri . set ( item . uri . toString ( ) , primary ) ;
@@ -1787,12 +1795,6 @@ export class AICustomizationListWidget extends Disposable {
17871795 this . lastCardFocusItemId = item . id ;
17881796 } ) ) ;
17891797 this . cardDisposables . add ( DOM . addDisposableListener ( primary , 'click' , ( ) => this . _onDidSelectItem . fire ( item ) ) ) ;
1790- this . cardDisposables . add ( DOM . addDisposableListener ( primary , 'keydown' , e => {
1791- if ( e . key === 'Enter' || e . key === ' ' ) {
1792- e . preventDefault ( ) ;
1793- this . _onDidSelectItem . fire ( item ) ;
1794- }
1795- } ) ) ;
17961798 this . cardDisposables . add ( this . hoverService . setupDelayedHover ( row , ( ) => ( {
17971799 content : `${ displayName } \n${ this . labelService . getUriLabel ( item . uri , { relative : item . source === AICustomizationSources . local } ) } ` ,
17981800 appearance : { compact : true , skipFadeInAnimation : true } ,
@@ -1826,6 +1828,13 @@ export class AICustomizationListWidget extends Disposable {
18261828 this . lastCardFocusItemId = item . id ;
18271829 } ) ) ;
18281830 this . cardDisposables . add ( more . onDidClick ( ( ) => this . showCardItemActions ( item , more . element ) ) ) ;
1831+ cardList . addItem ( {
1832+ row,
1833+ primaryAction : primary ,
1834+ label : displayName ,
1835+ actions : [ more . element ] ,
1836+ contextMenuAction : more . element ,
1837+ } ) ;
18291838 }
18301839
18311840 private getItemStatusLabel ( item : IAICustomizationListItem ) : string | undefined {
0 commit comments