55import * as i18n from '../../../core/i18n/i18n.js' ;
66import * as EmulationModel from '../../../models/emulation/emulation.js' ;
77import type * as Buttons from '../../../ui/components/buttons/buttons.js' ;
8+ import * as Cards from '../../../ui/components/cards/cards.js' ;
89import * as UI from '../../../ui/legacy/legacy.js' ;
910import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js' ;
1011
@@ -13,9 +14,13 @@ import devicesSettingsTabStyles from './devicesSettingsTab.css.js';
1314
1415const UIStrings = {
1516 /**
16- *@description Title for a section of the UI that shows all of the devices the user can emulate, in the Device Toolbar.
17+ * @description Title for a section of the UI that shows all of the custom devices the user can emulate, in the Device Toolbar.
1718 */
18- emulatedDevices : 'Emulated Devices' ,
19+ customDevices : 'Custom devices' ,
20+ /**
21+ * @description Title for a section of the UI that shows all of the default devices the user can emulate, in the Device Toolbar.
22+ */
23+ defaultDevices : 'Default devices' ,
1924 /**
2025 *@description Button to add a custom device (e.g. phone, tablet) the Device Toolbar.
2126 */
@@ -72,7 +77,8 @@ export class DevicesSettingsTab extends UI.Widget.VBox implements
7277 containerElement : HTMLElement ;
7378 private readonly addCustomButton : Buttons . Button . Button ;
7479 private readonly ariaSuccessMessageElement : HTMLElement ;
75- private readonly list : UI . ListWidget . ListWidget < EmulationModel . EmulatedDevices . EmulatedDevice > ;
80+ readonly #customDeviceList: UI . ListWidget . ListWidget < EmulationModel . EmulatedDevices . EmulatedDevice > ;
81+ readonly #defaultDeviceList: UI . ListWidget . ListWidget < EmulationModel . EmulatedDevices . EmulatedDevice > ;
7682 private muteUpdate : boolean ;
7783 private emulatedDevicesList : EmulationModel . EmulatedDevices . EmulatedDevicesList ;
7884 private editor ?: UI . ListWidget . Editor < EmulationModel . EmulatedDevices . EmulatedDevice > ;
@@ -82,25 +88,12 @@ export class DevicesSettingsTab extends UI.Widget.VBox implements
8288
8389 this . element . setAttribute ( 'jslog' , `${ VisualLogging . pane ( 'devices' ) } ` ) ;
8490
85- this . element . classList . add ( 'settings-tab-container' ) ;
86- this . element . classList . add ( 'devices-settings-tab' ) ;
87-
88- const header = this . element . createChild ( 'header' ) ;
89- UI . UIUtils . createTextChild ( header . createChild ( 'h1' ) , i18nString ( UIStrings . emulatedDevices ) ) ;
90- this . containerElement = this . element . createChild ( 'div' , 'settings-container-wrapper' )
91- . createChild ( 'div' , 'settings-tab settings-content settings-container' ) ;
92-
93- const buttonsRow = this . containerElement . createChild ( 'div' , 'devices-button-row' ) ;
94- this . addCustomButton = UI . UIUtils . createTextButton (
95- i18nString ( UIStrings . addCustomDevice ) , this . addCustomDevice . bind ( this ) , { jslogContext : 'add-custom-device' } ) ;
96- this . addCustomButton . id = 'custom-device-add-button' ;
97- buttonsRow . appendChild ( this . addCustomButton ) ;
98- this . ariaSuccessMessageElement = this . containerElement . createChild ( 'div' , 'device-success-message' ) ;
99- UI . ARIAUtils . markAsPoliteLiveRegion ( this . ariaSuccessMessageElement , false ) ;
91+ this . containerElement =
92+ this . contentElement . createChild ( 'div' , 'settings-card-container-wrapper' ) . createChild ( 'div' ) ;
93+ this . containerElement . classList . add ( 'settings-card-container' , 'ignore-list-settings' ) ;
10094
101- this . list = new UI . ListWidget . ListWidget ( this , false /* delegatesFocus */ ) ;
102- this . list . element . classList . add ( 'devices-list' ) ;
103- this . list . show ( this . containerElement ) ;
95+ this . #defaultDeviceList = new UI . ListWidget . ListWidget ( this , false /* delegatesFocus */ ) ;
96+ this . #defaultDeviceList. element . classList . add ( 'devices-list' , 'device-card-content' ) ;
10497
10598 this . muteUpdate = false ;
10699 this . emulatedDevicesList = EmulationModel . EmulatedDevices . EmulatedDevicesList . instance ( ) ;
@@ -109,34 +102,63 @@ export class DevicesSettingsTab extends UI.Widget.VBox implements
109102 this . emulatedDevicesList . addEventListener (
110103 EmulationModel . EmulatedDevices . Events . STANDARD_DEVICES_UPDATED , this . devicesUpdated , this ) ;
111104
112- this . setDefaultFocusedElement ( this . addCustomButton ) ;
105+ this . ariaSuccessMessageElement = this . contentElement . createChild ( 'div' , 'device-success-message' ) ;
106+ UI . ARIAUtils . markAsPoliteLiveRegion ( this . ariaSuccessMessageElement , false ) ;
107+
108+ this . addCustomButton = UI . UIUtils . createTextButton (
109+ i18nString ( UIStrings . addCustomDevice ) , this . addCustomDevice . bind ( this ) , { jslogContext : 'add-custom-device' } ) ;
110+ this . addCustomButton . id = 'custom-device-add-button' ;
111+
112+ const customSettings = document . createElement ( 'div' ) ;
113+ customSettings . classList . add ( 'device-card-content' ) ;
114+ customSettings . appendChild ( this . ariaSuccessMessageElement ) ;
115+ const deviceList = customSettings . createChild ( 'div' ) ;
116+ customSettings . appendChild ( this . addCustomButton ) ;
117+
118+ const customDevicesCard = new Cards . Card . Card ( ) ;
119+ customDevicesCard . data = {
120+ heading : i18nString ( UIStrings . customDevices ) ,
121+ content : [ customSettings ] ,
122+ } ;
123+ this . containerElement . appendChild ( customDevicesCard ) ;
124+
125+ this . #customDeviceList = new UI . ListWidget . ListWidget ( this , false /* delegatesFocus */ ) ;
126+ this . #customDeviceList. element . classList . add ( 'devices-list' ) ;
127+ this . #customDeviceList. show ( deviceList ) ;
128+
129+ const defaultDevicesCard = new Cards . Card . Card ( ) ;
130+ defaultDevicesCard . data = {
131+ heading : i18nString ( UIStrings . defaultDevices ) ,
132+ content : [ this . #defaultDeviceList. element ] ,
133+ } ;
134+ this . containerElement . appendChild ( defaultDevicesCard ) ;
113135 }
114136
115137 override wasShown ( ) : void {
116138 super . wasShown ( ) ;
117139 this . devicesUpdated ( ) ;
118140 this . registerCSSFiles ( [ devicesSettingsTabStyles ] ) ;
119- this . list . registerCSSFiles ( [ devicesSettingsTabStyles ] ) ;
141+ this . #defaultDeviceList. registerCSSFiles ( [ devicesSettingsTabStyles ] ) ;
142+ this . #customDeviceList. registerCSSFiles ( [ devicesSettingsTabStyles ] ) ;
120143 }
121144
122145 private devicesUpdated ( ) : void {
123146 if ( this . muteUpdate ) {
124147 return ;
125148 }
126149
127- this . list . clear ( ) ;
150+ this . #defaultDeviceList. clear ( ) ;
151+ this . #customDeviceList. clear ( ) ;
128152
129153 let devices = this . emulatedDevicesList . custom ( ) . slice ( ) ;
130154 for ( let i = 0 ; i < devices . length ; ++ i ) {
131- this . list . appendItem ( devices [ i ] , true ) ;
155+ this . #customDeviceList . appendItem ( devices [ i ] , true ) ;
132156 }
133157
134- this . list . appendSeparator ( ) ;
135-
136158 devices = this . emulatedDevicesList . standard ( ) . slice ( ) ;
137159 devices . sort ( EmulationModel . EmulatedDevices . EmulatedDevice . deviceComparator ) ;
138160 for ( let i = 0 ; i < devices . length ; ++ i ) {
139- this . list . appendItem ( devices [ i ] , false ) ;
161+ this . #defaultDeviceList . appendItem ( devices [ i ] , false ) ;
140162 }
141163 }
142164
@@ -157,7 +179,7 @@ export class DevicesSettingsTab extends UI.Widget.VBox implements
157179 device . horizontal . height = 400 ;
158180 device . vertical . width = 400 ;
159181 device . vertical . height = 700 ;
160- this . list . addNewItem ( this . emulatedDevicesList . custom ( ) . length , device ) ;
182+ this . #customDeviceList . addNewItem ( this . emulatedDevicesList . custom ( ) . length , device ) ;
161183 }
162184
163185 private toNumericInputValue ( value : number ) : string {
0 commit comments