Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/browser/ui/radio/radio.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { Widget } from '../widget.js';
7
import { ThemeIcon } from '../../../common/themables.js';
8
import { Emitter } from '../../../common/event.js';
9
import './radio.css';
10
import { $ } from '../../dom.js';
11
import { IHoverDelegate } from '../hover/hoverDelegate.js';
12
import { Button } from '../button/button.js';
13
import { DisposableMap, DisposableStore } from '../../../common/lifecycle.js';
14
import { createInstantHoverDelegate } from '../hover/hoverDelegateFactory.js';
15
16
export interface IRadioStyles {
17
readonly activeForeground?: string;
18
readonly activeBackground?: string;
19
readonly activeBorder?: string;
20
readonly inactiveForeground?: string;
21
readonly inactiveBackground?: string;
22
readonly inactiveHoverBackground?: string;
23
readonly inactiveBorder?: string;
24
}
25
26
export interface IRadioOptionItem {
27
readonly text: string;
28
readonly tooltip?: string;
29
readonly isActive?: boolean;
30
readonly disabled?: boolean;
31
}
32
33
export interface IRadioOptions {
34
readonly items: ReadonlyArray<IRadioOptionItem>;
35
readonly activeIcon?: ThemeIcon;
36
readonly hoverDelegate?: IHoverDelegate;
37
}
38
39
export class Radio extends Widget {
40
41
private readonly _onDidSelect = this._register(new Emitter<number>());
42
readonly onDidSelect = this._onDidSelect.event;
43
44
readonly domNode: HTMLElement;
45
46
private readonly hoverDelegate: IHoverDelegate;
47
48
private items: ReadonlyArray<IRadioOptionItem> = [];
49
private activeItem: IRadioOptionItem | undefined;
50
51
private readonly buttons = this._register(new DisposableMap<Button, { item: IRadioOptionItem; dispose(): void }>());
52
53
constructor(opts: IRadioOptions) {
54
super();
55
56
this.hoverDelegate = opts.hoverDelegate ?? this._register(createInstantHoverDelegate());
57
58
this.domNode = $('.monaco-custom-radio');
59
this.domNode.setAttribute('role', 'radio');
60
61
this.setItems(opts.items);
62
}
63
64
setItems(items: ReadonlyArray<IRadioOptionItem>): void {
65
this.buttons.clearAndDisposeAll();
66
this.items = items;
67
this.activeItem = this.items.find(item => item.isActive) ?? this.items[0];
68
for (let index = 0; index < this.items.length; index++) {
69
const item = this.items[index];
70
const disposables = new DisposableStore();
71
const button = disposables.add(new Button(this.domNode, {
72
hoverDelegate: this.hoverDelegate,
73
title: item.tooltip,
74
supportIcons: true,
75
}));
76
button.enabled = !item.disabled;
77
disposables.add(button.onDidClick(() => {
78
if (this.activeItem !== item) {
79
this.activeItem = item;
80
this.updateButtons();
81
this._onDidSelect.fire(index);
82
}
83
}));
84
this.buttons.set(button, { item, dispose: () => disposables.dispose() });
85
}
86
this.updateButtons();
87
}
88
89
setActiveItem(index: number): void {
90
if (index < 0 || index >= this.items.length) {
91
throw new Error('Invalid Index');
92
}
93
this.activeItem = this.items[index];
94
this.updateButtons();
95
}
96
97
setEnabled(enabled: boolean): void {
98
for (const [button] of this.buttons) {
99
button.enabled = enabled;
100
}
101
}
102
103
private updateButtons(): void {
104
let isActive = false;
105
for (const [button, { item }] of this.buttons) {
106
const isPreviousActive = isActive;
107
isActive = item === this.activeItem;
108
button.element.classList.toggle('active', isActive);
109
button.element.classList.toggle('previous-active', isPreviousActive);
110
button.label = item.text;
111
}
112
}
113
114
}
115
116