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.
Files changed (58) hide show
  1. package/aicontext.md +91 -5
  2. package/package.json +1 -1
  3. package/src/components/btngroup/btngroup.module.scss +1 -1
  4. package/src/components/btngroup/btngroup.ts +6 -1
  5. package/src/components/button/button.module.scss +4 -4
  6. package/src/components/button/button.ts +20 -0
  7. package/src/components/calendar/calendar.module.scss +2 -1
  8. package/src/components/calendar/calendar.ts +2 -1
  9. package/src/components/chart/chart.module.scss +4 -4
  10. package/src/components/checkbox/checkbox.module.scss +2 -1
  11. package/src/components/checkbox/checkbox.ts +1 -0
  12. package/src/components/colorpicker/colorpicker.module.scss +0 -1
  13. package/src/components/components.ts +1 -0
  14. package/src/components/dialog/dialog.module.scss +2 -2
  15. package/src/components/dialog/dialog.ts +1 -0
  16. package/src/components/dockingview/dockingview.module.scss +9 -8
  17. package/src/components/dockingview/dockingview.ts +1 -0
  18. package/src/components/form/form.module.scss +2 -2
  19. package/src/components/form/form.ts +1 -1
  20. package/src/components/gauge/gauge.module.scss +2 -2
  21. package/src/components/gridview/gridview.module.scss +0 -1
  22. package/src/components/input/input.module.scss +2 -2
  23. package/src/components/input/input.ts +3 -0
  24. package/src/components/keyboard/keyboard.ts +25 -3
  25. package/src/components/label/label.module.scss +1 -1
  26. package/src/components/listbox/listbox.module.scss +6 -3
  27. package/src/components/listbox/listbox.ts +2 -0
  28. package/src/components/menu/menu.module.scss +1 -2
  29. package/src/components/messages/messages.module.scss +11 -11
  30. package/src/components/messages/messages.ts +7 -1
  31. package/src/components/messages/pen-field.svg +1 -1
  32. package/src/components/panel/panel.module.scss +4 -3
  33. package/src/components/panel/panel.ts +1 -0
  34. package/src/components/popup/popup.module.scss +2 -3
  35. package/src/components/popup/popup.ts +1 -0
  36. package/src/components/propgrid/progrid.module.scss +4 -4
  37. package/src/components/radio/radio.module.scss +9 -3
  38. package/src/components/radio/radio.ts +7 -1
  39. package/src/components/select/select.module.scss +17 -12
  40. package/src/components/select/select.ts +9 -0
  41. package/src/components/settingsview/settingsview.module.scss +178 -0
  42. package/src/components/settingsview/settingsview.ts +289 -0
  43. package/src/components/spreadsheet/spreadsheet.module.scss +0 -1
  44. package/src/components/switch/switch.module.scss +3 -2
  45. package/src/components/switch/switch.ts +1 -0
  46. package/src/components/tabs/tabs.module.scss +6 -3
  47. package/src/components/tabs/tabs.ts +3 -0
  48. package/src/components/tag/tag.module.scss +1 -1
  49. package/src/components/textarea/textarea.module.scss +8 -1
  50. package/src/components/textarea/textarea.ts +3 -0
  51. package/src/components/themes.scss +25 -12
  52. package/src/components/tickline/tickline.module.scss +1 -1
  53. package/src/components/tooltips/tooltips.scss +4 -3
  54. package/src/components/tooltips/tooltips.ts +1 -0
  55. package/src/components/treeview/treeview.module.scss +6 -2
  56. package/src/components/treeview/treeview.ts +1 -0
  57. package/src/core/core_colors.ts +112 -17
  58. 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
+ }
@@ -333,7 +333,6 @@
333
333
 
334
334
  .cell-out {
335
335
  position: absolute;
336
- background-color: var( --color-gray-0 );
337
336
  width: 100%;
338
337
  height: var( --row-height );
339
338
  }
@@ -18,9 +18,10 @@
18
18
 
19
19
  :root {
20
20
  --switch-border: var( --border );
21
- --switch-background: #eee;
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: white;
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;
@@ -39,6 +39,7 @@ interface SwitchProps extends ComponentProps {
39
39
  * --switch-background
40
40
  * --switch-background-disabled
41
41
  * --switch-checked
42
+ * --switch-thumb
42
43
  * ```
43
44
  */
44
45
 
@@ -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-gray-7 );
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-gray-9 );
34
+ color: var( --tab-color-selected );
32
35
  }
33
36
 
34
37
  &:hover {
35
38
  background-color: unset;;
36
- color: black;
39
+ color: var( --tab-color-hover );
37
40
  border-bottom-color: var( --tab-border-hover );
38
41
  }
39
42
 
@@ -146,6 +146,9 @@ interface TabsProps extends Omit<ComponentProps,"content"> {
146
146
  * ```
147
147
  * --tab-border-selected
148
148
  * --tab-border-hover
149
+ * --tab-color-hover
150
+ * --tab-color
151
+ * --tab-color-selected
149
152
  * ```
150
153
  */
151
154
 
@@ -19,7 +19,7 @@
19
19
  --tag-border: var( --border );
20
20
  --tag-border-focus: var( --border-focus );
21
21
  --tag-background: var( --accent-background );
22
- --tag-color: black;
22
+ --tag-color: var( --text-primary );
23
23
  --tag-icon-color: var( --tag-color );
24
24
  }
25
25
 
@@ -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: white;
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: white;
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: var(--color-primary-a0);
95
+ --alert-color: #ffffff;
83
96
 
84
97
  --warning-background: var(--color-warning-a50);
85
- --warning-color: var(--color-primary-a0);
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: var(--color-primary-a0);
102
+ --success-color: #ffffff;
90
103
  }
@@ -18,7 +18,7 @@
18
18
  --tickline-axis-color: var( --border );
19
19
  --tickline-color: var( --accent-color );
20
20
  --tickline-width: 1px;
21
- --tickline-background: white;
21
+ --tickline-background: var( --background-primary );
22
22
  }
23
23
 
24
24
  .x4tickline {
@@ -18,14 +18,15 @@
18
18
 
19
19
  :root {
20
20
  --tooltip-caption-background: var( --color-primary-a70 );
21
- --tooltip-caption-color: white;
21
+ --tooltip-caption-color: var( --color-primary-a0 );
22
22
 
23
- --tooltip-icon-background: white;
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: white;
71
+ background-color: var( --tooltip-image-background );
71
72
  margin: 4px;
72
73
  }
73
74
  }
@@ -104,6 +104,7 @@ function closeTT( ) {
104
104
  * --tooltip-background
105
105
  * --tooltip-color
106
106
  * --tooltip-border
107
+ * --tooltip-image-background
107
108
  * ```
108
109
  */
109
110
 
@@ -17,10 +17,12 @@
17
17
 
18
18
  :root {
19
19
 
20
- --treeview-background: white;
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 {
@@ -72,6 +72,7 @@ export interface TreeviewEvents extends ComponentEvents {
72
72
  * @cssvar
73
73
  * ```
74
74
  * --treeview-background
75
+ * --treeitem-color
75
76
  * --treeitem-backgound-hover
76
77
  * --treeitem-color-hover
77
78
  * --treeitem-background-sel