Skip to content

Commit 61b0fe7

Browse files
authored
feat: add preview indicators (microsoft#231141)
1 parent 4b4bf8f commit 61b0fe7

File tree

3 files changed

+78
-11
lines changed

3 files changed

+78
-11
lines changed

src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css

+9
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,15 @@
404404
padding-bottom: 2px;
405405
}
406406

407+
.settings-editor > .settings-body .settings-tree-container .setting-item-contents .setting-item-title > .setting-indicators-container .setting-indicator.setting-item-preview {
408+
color: var(--vscode-badge-foreground);
409+
background: var(--vscode-badge-background);
410+
font-style: italic;
411+
margin-right: 4px;
412+
padding: 0px 4px 2px;
413+
border-radius: 4px;
414+
}
415+
407416
.settings-editor > .settings-body .settings-tree-container .setting-item-contents .setting-item-title .codicon {
408417
vertical-align: middle;
409418
padding-left: 1px;

src/vs/workbench/contrib/preferences/browser/settingsEditorSettingIndicators.ts

+68-11
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,16 @@ let cachedSyncIgnoredSettings: string[] = [];
6464
export class SettingsTreeIndicatorsLabel implements IDisposable {
6565
private readonly indicatorsContainerElement: HTMLElement;
6666

67+
private readonly previewIndicator: SettingIndicator;
6768
private readonly workspaceTrustIndicator: SettingIndicator;
6869
private readonly scopeOverridesIndicator: SettingIndicator;
6970
private readonly syncIgnoredIndicator: SettingIndicator;
7071
private readonly defaultOverrideIndicator: SettingIndicator;
71-
private readonly allIndicators: SettingIndicator[];
72+
73+
/** Indicators that each have their own square container at the top-right of the setting */
74+
private readonly isolatedIndicators: SettingIndicator[] = [];
75+
/** Indicators that end up wrapped in a parenthesis at the top-right of the setting */
76+
private readonly parenthesizedIndicators: SettingIndicator[];
7277

7378
private readonly keybindingListeners: DisposableStore = new DisposableStore();
7479
private focusedIndex = 0;
@@ -83,11 +88,14 @@ export class SettingsTreeIndicatorsLabel implements IDisposable {
8388
this.indicatorsContainerElement = DOM.append(container, $('.setting-indicators-container'));
8489
this.indicatorsContainerElement.style.display = 'inline';
8590

91+
this.previewIndicator = this.createPreviewIndicator();
92+
this.isolatedIndicators = [this.previewIndicator];
93+
8694
this.workspaceTrustIndicator = this.createWorkspaceTrustIndicator();
8795
this.scopeOverridesIndicator = this.createScopeOverridesIndicator();
8896
this.syncIgnoredIndicator = this.createSyncIgnoredIndicator();
8997
this.defaultOverrideIndicator = this.createDefaultOverrideIndicator();
90-
this.allIndicators = [this.workspaceTrustIndicator, this.scopeOverridesIndicator, this.syncIgnoredIndicator, this.defaultOverrideIndicator];
98+
this.parenthesizedIndicators = [this.workspaceTrustIndicator, this.scopeOverridesIndicator, this.syncIgnoredIndicator, this.defaultOverrideIndicator];
9199
}
92100

93101
private defaultHoverOptions: Partial<IHoverOptions> = {
@@ -206,24 +214,46 @@ export class SettingsTreeIndicatorsLabel implements IDisposable {
206214
};
207215
}
208216

217+
private createPreviewIndicator(): SettingIndicator {
218+
const disposables = new DisposableStore();
219+
const previewIndicator = $('span.setting-indicator.setting-item-preview');
220+
const previewLabel = disposables.add(new SimpleIconLabel(previewIndicator));
221+
222+
return {
223+
element: previewIndicator,
224+
label: previewLabel,
225+
disposables
226+
};
227+
}
228+
209229
private render() {
210-
const indicatorsToShow = this.allIndicators.filter(indicator => {
230+
this.indicatorsContainerElement.innerText = '';
231+
this.indicatorsContainerElement.style.display = 'none';
232+
233+
const isolatedIndicatorsToShow = this.isolatedIndicators.filter(indicator => {
211234
return indicator.element.style.display !== 'none';
212235
});
236+
if (isolatedIndicatorsToShow.length) {
237+
this.indicatorsContainerElement.style.display = 'inline';
238+
for (let i = 0; i < isolatedIndicatorsToShow.length; i++) {
239+
DOM.append(this.indicatorsContainerElement, isolatedIndicatorsToShow[i].element);
240+
}
241+
}
213242

214-
this.indicatorsContainerElement.innerText = '';
215-
this.indicatorsContainerElement.style.display = 'none';
216-
if (indicatorsToShow.length) {
243+
const parenthesizedIndicatorsToShow = this.parenthesizedIndicators.filter(indicator => {
244+
return indicator.element.style.display !== 'none';
245+
});
246+
if (parenthesizedIndicatorsToShow.length) {
217247
this.indicatorsContainerElement.style.display = 'inline';
218248
DOM.append(this.indicatorsContainerElement, $('span', undefined, '('));
219-
for (let i = 0; i < indicatorsToShow.length - 1; i++) {
220-
DOM.append(this.indicatorsContainerElement, indicatorsToShow[i].element);
249+
for (let i = 0; i < parenthesizedIndicatorsToShow.length - 1; i++) {
250+
DOM.append(this.indicatorsContainerElement, parenthesizedIndicatorsToShow[i].element);
221251
DOM.append(this.indicatorsContainerElement, $('span.comma', undefined, ' • '));
222252
}
223-
DOM.append(this.indicatorsContainerElement, indicatorsToShow[indicatorsToShow.length - 1].element);
253+
DOM.append(this.indicatorsContainerElement, parenthesizedIndicatorsToShow[parenthesizedIndicatorsToShow.length - 1].element);
224254
DOM.append(this.indicatorsContainerElement, $('span', undefined, ')'));
225-
this.resetIndicatorNavigationKeyBindings(indicatorsToShow);
226255
}
256+
this.resetIndicatorNavigationKeyBindings([...isolatedIndicatorsToShow, ...parenthesizedIndicatorsToShow]);
227257
}
228258

229259
private resetIndicatorNavigationKeyBindings(indicators: SettingIndicator[]) {
@@ -289,6 +319,30 @@ export class SettingsTreeIndicatorsLabel implements IDisposable {
289319
}
290320
}
291321

322+
updatePreviewIndicator(element: SettingsTreeSettingElement) {
323+
const isPreviewSetting = element.tags?.has('preview');
324+
// Hide experimental indicators for now until further review and experimental -> onExP migration.
325+
const isExperimentalSetting = false; // element.tags?.has('experimental');
326+
this.previewIndicator.element.style.display = (isPreviewSetting || isExperimentalSetting) ? 'inline' : 'none';
327+
this.previewIndicator.label.text = isPreviewSetting ?
328+
localize('previewLabel', "Preview") :
329+
localize('experimentalLabel', "Experimental");
330+
331+
const content = isPreviewSetting ?
332+
localize('previewSettingDescription', "The setting is in the process of becoming stable.") :
333+
localize('experimentalSettingDescription', "The setting is experimental and may change names or be removed.");
334+
const showHover = (focus: boolean) => {
335+
return this.hoverService.showHover({
336+
...this.defaultHoverOptions,
337+
content,
338+
target: this.previewIndicator.element
339+
}, focus);
340+
};
341+
this.addHoverDisposables(this.previewIndicator.disposables, this.previewIndicator.element, showHover);
342+
343+
this.render();
344+
}
345+
292346
private getInlineScopeDisplayText(completeScope: string): string {
293347
const [scope, language] = completeScope.split(':');
294348
const localizedScope = scope === 'user' ?
@@ -302,7 +356,10 @@ export class SettingsTreeIndicatorsLabel implements IDisposable {
302356

303357
dispose() {
304358
this.keybindingListeners.dispose();
305-
for (const indicator of this.allIndicators) {
359+
for (const indicator of this.isolatedIndicators) {
360+
indicator.disposables.dispose();
361+
}
362+
for (const indicator of this.parenthesizedIndicators) {
306363
indicator.disposables.dispose();
307364
}
308365
}

src/vs/workbench/contrib/preferences/browser/settingsTree.ts

+1
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,7 @@ export abstract class AbstractSettingRenderer extends Disposable implements ITre
994994
template.indicatorsLabel.updateWorkspaceTrust(element);
995995
template.indicatorsLabel.updateSyncIgnored(element, this.ignoredSettings);
996996
template.indicatorsLabel.updateDefaultOverrideIndicator(element);
997+
template.indicatorsLabel.updatePreviewIndicator(element);
997998
template.elementDisposables.add(this.onDidChangeIgnoredSettings(() => {
998999
template.indicatorsLabel.updateSyncIgnored(element, this.ignoredSettings);
9991000
}));

0 commit comments

Comments
 (0)