x4js 2.3.21 → 2.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/aicontext.md +91 -5
- package/package.json +1 -1
- package/src/components/btngroup/btngroup.module.scss +1 -1
- package/src/components/btngroup/btngroup.ts +6 -1
- package/src/components/button/button.module.scss +4 -4
- package/src/components/button/button.ts +20 -0
- package/src/components/calendar/calendar.module.scss +2 -1
- package/src/components/calendar/calendar.ts +2 -1
- package/src/components/chart/chart.module.scss +4 -4
- package/src/components/checkbox/checkbox.module.scss +2 -1
- package/src/components/checkbox/checkbox.ts +1 -0
- package/src/components/colorpicker/colorpicker.module.scss +0 -1
- package/src/components/components.ts +1 -0
- package/src/components/dialog/dialog.module.scss +2 -2
- package/src/components/dialog/dialog.ts +1 -0
- package/src/components/dockingview/dockingview.module.scss +9 -8
- package/src/components/dockingview/dockingview.ts +1 -0
- package/src/components/form/form.module.scss +2 -2
- package/src/components/form/form.ts +1 -1
- package/src/components/gauge/gauge.module.scss +2 -2
- package/src/components/gridview/gridview.module.scss +0 -1
- package/src/components/input/input.module.scss +2 -2
- package/src/components/input/input.ts +3 -0
- package/src/components/keyboard/keyboard.ts +25 -3
- package/src/components/label/label.module.scss +1 -1
- package/src/components/listbox/listbox.module.scss +6 -3
- package/src/components/listbox/listbox.ts +2 -0
- package/src/components/menu/menu.module.scss +1 -2
- package/src/components/messages/messages.module.scss +11 -11
- package/src/components/messages/messages.ts +7 -1
- package/src/components/messages/pen-field.svg +1 -1
- package/src/components/panel/panel.module.scss +4 -3
- package/src/components/panel/panel.ts +1 -0
- package/src/components/popup/popup.module.scss +2 -3
- package/src/components/popup/popup.ts +1 -0
- package/src/components/propgrid/progrid.module.scss +4 -4
- package/src/components/radio/radio.module.scss +9 -3
- package/src/components/radio/radio.ts +7 -1
- package/src/components/select/select.module.scss +17 -12
- package/src/components/select/select.ts +9 -0
- package/src/components/settingsview/settingsview.module.scss +178 -0
- package/src/components/settingsview/settingsview.ts +289 -0
- package/src/components/spreadsheet/spreadsheet.module.scss +0 -1
- package/src/components/switch/switch.module.scss +3 -2
- package/src/components/switch/switch.ts +1 -0
- package/src/components/tabs/tabs.module.scss +6 -3
- package/src/components/tabs/tabs.ts +3 -0
- package/src/components/tag/tag.module.scss +1 -1
- package/src/components/textarea/textarea.module.scss +8 -1
- package/src/components/textarea/textarea.ts +3 -0
- package/src/components/themes.scss +25 -12
- package/src/components/tickline/tickline.module.scss +1 -1
- package/src/components/tooltips/tooltips.scss +4 -3
- package/src/components/tooltips/tooltips.ts +1 -0
- package/src/components/treeview/treeview.module.scss +6 -2
- package/src/components/treeview/treeview.ts +1 -0
- package/src/core/core_colors.ts +112 -17
- package/src/core/core_i18n.ts +157 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ___ ___ __
|
|
3
|
+
* \ \/ / / _
|
|
4
|
+
* \ / /_| |_
|
|
5
|
+
* / \____ _|
|
|
6
|
+
* /__/\__\ |_|
|
|
7
|
+
*
|
|
8
|
+
* @file settingsview.ts
|
|
9
|
+
* @author Etienne Cochard
|
|
10
|
+
*
|
|
11
|
+
* @copyright (c) 2026 R-libre ingenierie
|
|
12
|
+
*
|
|
13
|
+
* Use of this source code is governed by an MIT-style license
|
|
14
|
+
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
|
+
**/
|
|
16
|
+
|
|
17
|
+
import { Component, ComponentEvent, ComponentEvents } from '../../core/component';
|
|
18
|
+
import { EventCallback } from '../../core/core_events';
|
|
19
|
+
import { class_ns } from '../../core/core_tools';
|
|
20
|
+
|
|
21
|
+
import { BoxProps, HBox, VBox } from '../boxes/boxes';
|
|
22
|
+
import { Input } from '../input/input';
|
|
23
|
+
import { Label } from '../label/label';
|
|
24
|
+
import { Listbox } from '../listbox/listbox';
|
|
25
|
+
|
|
26
|
+
import { _tr } from '../../x4.js';
|
|
27
|
+
|
|
28
|
+
import "./settingsview.module.scss"
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
export interface SettingItemProps extends BoxProps {
|
|
35
|
+
title: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
content: Component | Component[]; // its controls
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* one setting: its name, what it does, then its controls on a line that wraps.
|
|
42
|
+
* It has no value of its own: its controls keep theirs. To read and write them
|
|
43
|
+
* together, put the items in a Form and give the controls a name.
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
@class_ns( "x4" )
|
|
47
|
+
export class SettingItem extends VBox<SettingItemProps> {
|
|
48
|
+
|
|
49
|
+
constructor( props: SettingItemProps ) {
|
|
50
|
+
// the content goes under the name and the description, not in the box itself
|
|
51
|
+
super( { ...props, content: undefined } );
|
|
52
|
+
|
|
53
|
+
this.setContent( [
|
|
54
|
+
new Label( { cls: "name", text: props.title } ),
|
|
55
|
+
props.description ? new Label( { cls: "description", text: props.description } ) : null,
|
|
56
|
+
new HBox( { cls: "controls", content: props.content } ),
|
|
57
|
+
] );
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* the text a search looks in: the name and the description
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
getSearchText( ) {
|
|
65
|
+
return `${this.props.title} ${this.props.description ?? ""}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* a section: a panel, its title on a band, then its content
|
|
71
|
+
*/
|
|
72
|
+
|
|
73
|
+
export interface SettingsSection {
|
|
74
|
+
id: string;
|
|
75
|
+
title: string;
|
|
76
|
+
description?: string; // under the title
|
|
77
|
+
content: Component[]; // SettingItem, Form of SettingItem, or any component
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface EvSectionChange extends ComponentEvent {
|
|
81
|
+
readonly section: string; // the id of the section now at the top
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface SettingsViewProps extends BoxProps {
|
|
85
|
+
sections?: SettingsSection[];
|
|
86
|
+
searchable?: boolean; // a search field above the sections
|
|
87
|
+
searchPlaceholder?: string; // _tr.global.settings.search when missing
|
|
88
|
+
noMatch?: string; // shown when the search finds nothing; _tr.global.settings.nomatch when missing
|
|
89
|
+
sectionChange?: EventCallback<EvSectionChange>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface SettingsViewEvents extends ComponentEvents {
|
|
93
|
+
sectionChange: EvSectionChange;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* text compared without case nor accents
|
|
98
|
+
*/
|
|
99
|
+
|
|
100
|
+
function normalize( text: string ) {
|
|
101
|
+
return text.normalize( "NFD" ).replace( /[̀-ͯ]/g, "" ).toLowerCase( );
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* a page of settings, as the settings of VS Code: the summary of the sections
|
|
106
|
+
* on the left, the sections on the right, one after the other. A click in the
|
|
107
|
+
* summary brings its section to the top; the summary follows the scroll.
|
|
108
|
+
* With searchable, a field above them filters the settings.
|
|
109
|
+
*
|
|
110
|
+
* @cssvar
|
|
111
|
+
* ```
|
|
112
|
+
* --settingsview-toc-width
|
|
113
|
+
* --settingsview-section-background
|
|
114
|
+
* --settingsview-section-title-background
|
|
115
|
+
* --settingsview-hover-background
|
|
116
|
+
* --settingsview-marker
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
|
|
120
|
+
@class_ns( "x4" )
|
|
121
|
+
export class SettingsView<P extends SettingsViewProps = SettingsViewProps> extends VBox<P,SettingsViewEvents> {
|
|
122
|
+
|
|
123
|
+
// fields, not refs: refs belong to the classes that derive from this one
|
|
124
|
+
private _search: Input = null;
|
|
125
|
+
private _toc: Listbox;
|
|
126
|
+
private _view: VBox;
|
|
127
|
+
private _noMatch: Label;
|
|
128
|
+
|
|
129
|
+
// shown: kept by the search (isVisible is false too while the view is hidden)
|
|
130
|
+
private _sections: { section: SettingsSection, box: VBox, shown: boolean }[] = [];
|
|
131
|
+
private _current = ""; // the id of the section at the top
|
|
132
|
+
|
|
133
|
+
constructor( props: P ) {
|
|
134
|
+
super( props );
|
|
135
|
+
this.mapPropEvents( props, "sectionChange" );
|
|
136
|
+
|
|
137
|
+
this.setContent( [
|
|
138
|
+
props.searchable ? new HBox( {
|
|
139
|
+
cls: "search",
|
|
140
|
+
content: this._search = new Input( {
|
|
141
|
+
type: "text",
|
|
142
|
+
placeholder: props.searchPlaceholder ?? _tr.global.settings.search,
|
|
143
|
+
change: ( ) => this._filter( ),
|
|
144
|
+
} ),
|
|
145
|
+
} ) : null,
|
|
146
|
+
|
|
147
|
+
new HBox( {
|
|
148
|
+
cls: "body",
|
|
149
|
+
flex: true,
|
|
150
|
+
content: [
|
|
151
|
+
this._toc = new Listbox( {
|
|
152
|
+
cls: "toc",
|
|
153
|
+
items: [],
|
|
154
|
+
selectionChange: ( ev ) => this.showSection( ev.selection[0] as string ),
|
|
155
|
+
} ),
|
|
156
|
+
this._view = new VBox( { cls: "sections", flex: true } ),
|
|
157
|
+
],
|
|
158
|
+
} ),
|
|
159
|
+
] );
|
|
160
|
+
|
|
161
|
+
this._noMatch = new Label( { cls: "nomatch", text: props.noMatch ?? _tr.global.settings.nomatch, hidden: true } );
|
|
162
|
+
this._view.addDOMEvent( "scroll", ( ) => this._followScroll( ) );
|
|
163
|
+
|
|
164
|
+
// Escape empties the search
|
|
165
|
+
if( this._search ) {
|
|
166
|
+
this._search.addDOMEvent( "keydown", ( ev ) => {
|
|
167
|
+
if( ev.key == "Escape" && this._search.getValue( ) ) {
|
|
168
|
+
this._search.setValue( "" );
|
|
169
|
+
this._filter( );
|
|
170
|
+
}
|
|
171
|
+
} );
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if( props.sections ) {
|
|
175
|
+
this.setSections( props.sections );
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* the sections, in their order; for a class that builds them in its
|
|
181
|
+
* constructor, after super( )
|
|
182
|
+
*/
|
|
183
|
+
|
|
184
|
+
setSections( sections: SettingsSection[] ) {
|
|
185
|
+
this._sections = sections.map( section => ( {
|
|
186
|
+
section,
|
|
187
|
+
shown: true,
|
|
188
|
+
box: new VBox( {
|
|
189
|
+
cls: "section",
|
|
190
|
+
content: [
|
|
191
|
+
new Label( { cls: "title", text: section.title } ),
|
|
192
|
+
section.description ? new Label( { cls: "description", text: section.description } ) : null,
|
|
193
|
+
...section.content,
|
|
194
|
+
],
|
|
195
|
+
} ),
|
|
196
|
+
} ) );
|
|
197
|
+
|
|
198
|
+
this._view.setContent( [ ...this._sections.map( s => s.box ), this._noMatch ] );
|
|
199
|
+
this._current = "";
|
|
200
|
+
this._filter( );
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* brings a section to the top of the view
|
|
205
|
+
*/
|
|
206
|
+
|
|
207
|
+
showSection( id: string, smooth = true ) {
|
|
208
|
+
this._sections.find( s => s.section.id == id )?.box.scrollIntoView( { behavior: smooth ? "smooth" : "auto", block: "start" } );
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* the id of the section at the top of the view
|
|
213
|
+
*/
|
|
214
|
+
|
|
215
|
+
getSection( ) {
|
|
216
|
+
return this._current;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* shows what the search finds; everything when it is empty. A section
|
|
221
|
+
* whose title or description holds the words is shown whole; otherwise
|
|
222
|
+
* only its settings that hold them, and what holds those settings.
|
|
223
|
+
*/
|
|
224
|
+
|
|
225
|
+
private _filter( ) {
|
|
226
|
+
const text = this._search ? this._search.getValue( ) : "";
|
|
227
|
+
const words = normalize( text ).split( /\s+/ ).filter( w => w );
|
|
228
|
+
const matches = ( text: string ) => {
|
|
229
|
+
const t = normalize( text );
|
|
230
|
+
return words.every( w => t.includes( w ) );
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
let found = false;
|
|
234
|
+
for( const s of this._sections ) {
|
|
235
|
+
const { section, box } = s;
|
|
236
|
+
const whole = !words.length || matches( `${section.title} ${section.description ?? ""}` );
|
|
237
|
+
let shown = whole;
|
|
238
|
+
|
|
239
|
+
for( const c of section.content ) {
|
|
240
|
+
const items = c instanceof SettingItem ? [c] : c.enumChildComponents( true ).filter( x => x instanceof SettingItem ) as SettingItem[];
|
|
241
|
+
let some = false;
|
|
242
|
+
for( const item of items ) {
|
|
243
|
+
const ok = whole || matches( item.getSearchText( ) );
|
|
244
|
+
item.show( ok );
|
|
245
|
+
some ||= ok;
|
|
246
|
+
}
|
|
247
|
+
// what holds no setting (a table, a text) is shown with its whole section only
|
|
248
|
+
c.show( whole || some );
|
|
249
|
+
shown ||= some;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
s.shown = shown;
|
|
253
|
+
box.show( shown );
|
|
254
|
+
found ||= shown;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
this._noMatch.show( !found );
|
|
258
|
+
|
|
259
|
+
// the summary lists the sections shown; the last one is as high as the
|
|
260
|
+
// view at least: a click in the summary can bring every section to the top
|
|
261
|
+
const shown = this._sections.filter( s => s.shown );
|
|
262
|
+
this._sections.forEach( s => s.box.setClass( "last", s == shown[shown.length - 1] ) );
|
|
263
|
+
this._toc.clearSelection( false );
|
|
264
|
+
this._toc.setItems( shown.map( s => ( { id: s.section.id, text: s.section.title } ) ) );
|
|
265
|
+
this._current = "";
|
|
266
|
+
this._followScroll( );
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* the summary on the section at the top of the view; the first one while the view is hidden
|
|
271
|
+
*/
|
|
272
|
+
|
|
273
|
+
private _followScroll( ) {
|
|
274
|
+
const view = this._view.getBoundingRect( );
|
|
275
|
+
|
|
276
|
+
let current = "";
|
|
277
|
+
for( const { section, box, shown } of this._sections ) {
|
|
278
|
+
if( shown && ( !current || ( view.height && box.getBoundingRect( ).top <= view.top + 40 ) ) ) {
|
|
279
|
+
current = section.id;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
this._toc.select( current, false );
|
|
284
|
+
if( current != this._current ) {
|
|
285
|
+
this._current = current;
|
|
286
|
+
this.fire( "sectionChange", { section: current } );
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
@@ -18,9 +18,10 @@
|
|
|
18
18
|
|
|
19
19
|
:root {
|
|
20
20
|
--switch-border: var( --border );
|
|
21
|
-
--switch-background:
|
|
21
|
+
--switch-background: var( --background-hover );
|
|
22
22
|
--switch-background-disabled: var( --disabled-background );
|
|
23
23
|
--switch-checked: var( --accent-background );
|
|
24
|
+
--switch-thumb: var( --background-primary );
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
.x4switch {
|
|
@@ -88,7 +89,7 @@
|
|
|
88
89
|
height: 1rem;
|
|
89
90
|
|
|
90
91
|
border-radius: 8px;
|
|
91
|
-
background-color:
|
|
92
|
+
background-color: var( --switch-thumb );
|
|
92
93
|
box-shadow: 0 0 2px rgba(0,0,0,0.5);
|
|
93
94
|
|
|
94
95
|
transition: left ease 0.2s;
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
:root {
|
|
4
4
|
--tab-border-selected: var( --accent-background );
|
|
5
5
|
--tab-border-hover: var( --accent-background-hover );
|
|
6
|
+
--tab-color-hover: var( --text-primary );
|
|
7
|
+
--tab-color: var( --text-primary );
|
|
8
|
+
--tab-color-selected: var( --text-primary );
|
|
6
9
|
}
|
|
7
10
|
|
|
8
11
|
.x4tabs {
|
|
@@ -20,7 +23,7 @@
|
|
|
20
23
|
.x4button {
|
|
21
24
|
border: none;
|
|
22
25
|
border-bottom: 2px solid transparent;
|
|
23
|
-
color: var( --color
|
|
26
|
+
color: var( --tab-color );
|
|
24
27
|
margin: 0;
|
|
25
28
|
outline: none;
|
|
26
29
|
transition: border-color 0.2s ease;
|
|
@@ -28,12 +31,12 @@
|
|
|
28
31
|
&.selected {
|
|
29
32
|
border-bottom-color: var( --tab-border-selected );
|
|
30
33
|
font-weight: bold;
|
|
31
|
-
color: var( --color-
|
|
34
|
+
color: var( --tab-color-selected );
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
&:hover {
|
|
35
38
|
background-color: unset;;
|
|
36
|
-
color:
|
|
39
|
+
color: var( --tab-color-hover );
|
|
37
40
|
border-bottom-color: var( --tab-border-hover );
|
|
38
41
|
}
|
|
39
42
|
|
|
@@ -20,6 +20,9 @@
|
|
|
20
20
|
--textarea-border: var( --border );
|
|
21
21
|
--textarea-border-focus: var( --border-focus );
|
|
22
22
|
--textarea-selection: var( --accent-background );
|
|
23
|
+
--textarea-selection-color: var( --accent-color );
|
|
24
|
+
--textarea-background: var( --background-input );
|
|
25
|
+
--textarea-color: var( --text-primary );
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
.x4simpletextarea {
|
|
@@ -36,6 +39,10 @@
|
|
|
36
39
|
outline: none;
|
|
37
40
|
font: inherit;
|
|
38
41
|
|
|
42
|
+
// as the ones of an input
|
|
43
|
+
background-color: var( --textarea-background );
|
|
44
|
+
color: var( --textarea-color );
|
|
45
|
+
|
|
39
46
|
border: 1px solid var( --textarea-border );
|
|
40
47
|
|
|
41
48
|
&:focus {
|
|
@@ -44,7 +51,7 @@
|
|
|
44
51
|
|
|
45
52
|
&::selection {
|
|
46
53
|
background-color: var( --textarea-selection );
|
|
47
|
-
color:
|
|
54
|
+
color: var( --textarea-selection-color );
|
|
48
55
|
}
|
|
49
56
|
|
|
50
57
|
// as the one of an input
|
|
@@ -136,6 +136,9 @@ export class SimpleTextArea extends Component<SimpleTextAreaProps,TextAreaEvents
|
|
|
136
136
|
* --textarea-border
|
|
137
137
|
* --textarea-border-focus
|
|
138
138
|
* --textarea-selection
|
|
139
|
+
* --textarea-selection-color
|
|
140
|
+
* --textarea-background
|
|
141
|
+
* --textarea-color
|
|
139
142
|
* ```
|
|
140
143
|
*/
|
|
141
144
|
|
|
@@ -44,27 +44,39 @@ $color--interval: 8.4%;
|
|
|
44
44
|
--color-success-a60: #{color.adjust(#10c01f, $lightness: -10%)};
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// the greys are mixes of the two ends of the scale: #999 with a0 white and a100 black,
|
|
48
|
+
// light on dark when a theme reverses the scale
|
|
49
|
+
|
|
47
50
|
:root {
|
|
48
51
|
// Backgrounds
|
|
49
52
|
--background-primary: var(--color-primary-a0);
|
|
50
53
|
--background-secondary: var(--color-primary-a10);
|
|
51
|
-
--background-ternary: #f4f4f4
|
|
54
|
+
--background-ternary: color-mix(in srgb, var(--color-primary-a100) 4.3%, var(--color-primary-a0)); // #f4f4f4
|
|
55
|
+
--background-hover: color-mix(in srgb, var(--color-primary-a100) 6.7%, var(--color-primary-a0)); // #eee
|
|
56
|
+
--background-active: color-mix(in srgb, var(--color-primary-a100) 20%, var(--color-primary-a0)); // #ccc
|
|
57
|
+
--background-input: color-mix(in srgb, var(--color-primary-a0) 60%, transparent); // white at 60%
|
|
52
58
|
|
|
53
59
|
// Texts
|
|
54
60
|
--text-primary: var(--color-primary-a100);
|
|
55
|
-
--text-secondary: #999
|
|
56
|
-
--text-ternary: #666
|
|
61
|
+
--text-secondary: color-mix(in srgb, var(--color-primary-a100) 40%, var(--color-primary-a0)); // #999
|
|
62
|
+
--text-ternary: color-mix(in srgb, var(--color-primary-a100) 60%, var(--color-primary-a0)); // #666
|
|
57
63
|
|
|
58
64
|
// Disabled
|
|
59
|
-
--disabled-background: #ccc
|
|
60
|
-
--disabled-color:
|
|
61
|
-
--disabled-color-dark: #aaa
|
|
65
|
+
--disabled-background: color-mix(in srgb, var(--color-primary-a100) 20%, var(--color-primary-a0)); // #ccc
|
|
66
|
+
--disabled-color: var(--color-primary-a0);
|
|
67
|
+
--disabled-color-dark: color-mix(in srgb, var(--color-primary-a100) 33.3%, var(--color-primary-a0)); // #aaa
|
|
68
|
+
--disabled-color-light: color-mix(in srgb, var(--color-primary-a100) 20%, var(--color-primary-a0)); // #ccc
|
|
69
|
+
|
|
70
|
+
// Icons
|
|
71
|
+
--icon-color: color-mix(in srgb, var(--color-primary-a100) 44%, transparent); // black at 44%
|
|
72
|
+
--icon-color-active: color-mix(in srgb, var(--accent-color) 64%, transparent); // white at 64%
|
|
62
73
|
|
|
63
74
|
// Accents
|
|
64
75
|
--accent-background: var(--color-primary-a60);
|
|
65
76
|
--accent-background-hover: var(--color-primary-a55);
|
|
66
77
|
--accent-background-focus: var(--color-primary-a70);
|
|
67
78
|
--accent-background-active: var(--color-primary-a80);
|
|
79
|
+
--accent-background-light: color-mix(in srgb, var(--accent-background) 25%, transparent); // the accent at 25%
|
|
68
80
|
|
|
69
81
|
--accent-color: var(--color-primary-a0);
|
|
70
82
|
--accent-color-hover: var(--color-primary-a0);
|
|
@@ -72,19 +84,20 @@ $color--interval: 8.4%;
|
|
|
72
84
|
--accent-color-active: var(--color-primary-a0);
|
|
73
85
|
|
|
74
86
|
// Borders
|
|
75
|
-
--border: #e1e1e1
|
|
76
|
-
--border-light: #eaeaea
|
|
77
|
-
--border-hover: #c2c2c2
|
|
87
|
+
--border: color-mix(in srgb, var(--color-primary-a100) 11.8%, var(--color-primary-a0)); // #e1e1e1
|
|
88
|
+
--border-light: color-mix(in srgb, var(--color-primary-a100) 8.2%, var(--color-primary-a0)); // #eaeaea
|
|
89
|
+
--border-hover: color-mix(in srgb, var(--color-primary-a100) 23.9%, var(--color-primary-a0)); // #c2c2c2
|
|
78
90
|
--border-focus: var(--accent-background);
|
|
79
91
|
|
|
92
|
+
// the red, orange and green do not follow the scale: their text stays white
|
|
80
93
|
--alert-background: var(--color-danger-a50);
|
|
81
94
|
--alert-background-active: var(--color-danger-a60);
|
|
82
|
-
--alert-color:
|
|
95
|
+
--alert-color: #ffffff;
|
|
83
96
|
|
|
84
97
|
--warning-background: var(--color-warning-a50);
|
|
85
|
-
--warning-color:
|
|
98
|
+
--warning-color: #ffffff;
|
|
86
99
|
|
|
87
100
|
--success-background: var(--color-success-a50);
|
|
88
101
|
--success-background-active: var(--color-success-a60);
|
|
89
|
-
--success-color:
|
|
102
|
+
--success-color: #ffffff;
|
|
90
103
|
}
|
|
@@ -18,14 +18,15 @@
|
|
|
18
18
|
|
|
19
19
|
:root {
|
|
20
20
|
--tooltip-caption-background: var( --color-primary-a70 );
|
|
21
|
-
--tooltip-caption-color:
|
|
21
|
+
--tooltip-caption-color: var( --color-primary-a0 );
|
|
22
22
|
|
|
23
|
-
--tooltip-icon-background:
|
|
23
|
+
--tooltip-icon-background: var( --color-primary-a0 );
|
|
24
24
|
--tooltip-icon-color: var( --color-primary-a70 );
|
|
25
25
|
|
|
26
26
|
--tooltip-background: var( --color-primary-a10 ); //white;
|
|
27
27
|
--tooltip-color: var( --color-primary-a90 );
|
|
28
28
|
--tooltip-border: var( --color-primary-a20 );
|
|
29
|
+
--tooltip-image-background: var( --background-primary );
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
.x4tooltip {
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
img {
|
|
68
69
|
max-width: 100px;
|
|
69
70
|
max-height: 50px;
|
|
70
|
-
background-color:
|
|
71
|
+
background-color: var( --tooltip-image-background );
|
|
71
72
|
margin: 4px;
|
|
72
73
|
}
|
|
73
74
|
}
|
|
@@ -17,10 +17,12 @@
|
|
|
17
17
|
|
|
18
18
|
:root {
|
|
19
19
|
|
|
20
|
-
--treeview-background:
|
|
20
|
+
--treeview-background: var( --background-primary );
|
|
21
|
+
|
|
22
|
+
--treeitem-color: var( --text-primary );
|
|
21
23
|
|
|
22
24
|
--treeitem-backgound-hover: var( --background-secondary );
|
|
23
|
-
--treeitem-color-hover: var( );
|
|
25
|
+
--treeitem-color-hover: var( --text-primary );
|
|
24
26
|
|
|
25
27
|
--treeitem-background-sel: var( --accent-background );
|
|
26
28
|
--treeitem-color-sel: var( --accent-color );
|
|
@@ -97,6 +99,8 @@
|
|
|
97
99
|
|
|
98
100
|
&:hover {
|
|
99
101
|
background-color: var( --treeitem-backgound-hover );
|
|
102
|
+
--label-color: var( --treeitem-color-hover );
|
|
103
|
+
--label-icon-color: var( --treeitem-color-hover );
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
&.selected {
|