x4js 2.3.22 → 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 +10 -1
- 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/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/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 +1 -1
- 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/aicontext.md
CHANGED
|
@@ -1030,6 +1030,8 @@ interface ButtonProps extends ComponentProps {
|
|
|
1030
1030
|
tabindex?: number | boolean
|
|
1031
1031
|
autorepeat?: number | boolean // true=200ms; number=interval (first fire after 500ms)
|
|
1032
1032
|
click?: EventCallback<EvClick>
|
|
1033
|
+
menu?: MenuElement[] | (() => MenuElement[]) // a click opens this Menu under the button, in place of the click event;
|
|
1034
|
+
// a function is called at each click; the button gets the class "with-menu"
|
|
1033
1035
|
}
|
|
1034
1036
|
class Button extends Component {
|
|
1035
1037
|
click(): void // simulate a click
|
|
@@ -1531,8 +1533,15 @@ class Timer { setTimeout; clearTimeout; setInterval; clearInterval; clearAllTime
|
|
|
1531
1533
|
|
|
1532
1534
|
class Color {
|
|
1533
1535
|
// new Color(value) | new Color(r,g,b,a?) a: 0..1, default 1
|
|
1536
|
+
// value: "#rgb", "#rrggbb", "#rrggbbaa", "rgb()", "rgba()", a name ("cyan", "transparent"), "var(--name)",
|
|
1537
|
+
// and any other colour the browser knows (hsl(), oklch(), color-mix()), read from the pixel it paints
|
|
1534
1538
|
setValue(value): this; setRgb(r,g,b,a?): this; setHsv(h,s,v,a?): this; setAlpha(a): this
|
|
1535
|
-
getAlpha(): number
|
|
1539
|
+
getAlpha(): number
|
|
1540
|
+
lighten(percent): this; darken(percent): this // toward white / black, 0-100, each component rounded
|
|
1541
|
+
mix(other: Color, amount): this // amount 0-1: 0 keeps this color, 1 gives the other one; alpha too
|
|
1542
|
+
luminance(): number // WCAG relative luminance, 0 (black) to 1 (white); alpha not used
|
|
1543
|
+
contrast(other: Color): number // WCAG ratio, 1 to 21
|
|
1544
|
+
textColor(light?: Color, dark?: Color): Color // a copy of the one of the two that contrasts most with this color; white and black by default
|
|
1536
1545
|
isInvalid(): boolean // the last setValue could not be read (the color is red); setRgb/setHsv make it valid
|
|
1537
1546
|
toHexString(): string; toNumber(): number
|
|
1538
1547
|
toRgbString(withAlpha = false): string // "rgb(r,g,b)"; true: "rgba(r,g,b,0.500)" when not opaque, "rgb(...)" when opaque
|
package/package.json
CHANGED
|
@@ -56,7 +56,12 @@ interface BtnGroupProps extends Omit<ComponentProps,"content"> {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
|
-
*
|
|
59
|
+
*
|
|
60
|
+
* @cssvar
|
|
61
|
+
* ```
|
|
62
|
+
* --btngroup-background
|
|
63
|
+
* ```
|
|
64
|
+
* a packed group draws its buttons with the --ol-button-* variables of Button
|
|
60
65
|
*/
|
|
61
66
|
|
|
62
67
|
@class_ns( "x4" )
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
--button-background-disabled: var( --disabled-background );
|
|
33
33
|
--button-color-disabled: var( --disabled-color );
|
|
34
34
|
|
|
35
|
-
--button-icon-color:
|
|
35
|
+
--button-icon-color: var( --icon-color-active );
|
|
36
36
|
|
|
37
37
|
// outline
|
|
38
38
|
--ol-button-background: var( --background-primary );
|
|
39
|
-
--ol-button-background-active:
|
|
39
|
+
--ol-button-background-active: var( --background-active );
|
|
40
40
|
--ol-button-color-active: var( --text-primary );
|
|
41
|
-
--ol-button-background-hover:
|
|
41
|
+
--ol-button-background-hover: var( --background-hover );
|
|
42
42
|
--ol-button-color-hover: var( --text-primary );
|
|
43
|
-
--ol-button-color-disabled:
|
|
43
|
+
--ol-button-color-disabled: var( --disabled-color-light );
|
|
44
44
|
|
|
45
45
|
--ol-button-color: var( --text-primary );
|
|
46
46
|
--ol-button-border: var( --border );
|
|
@@ -71,6 +71,14 @@ export interface ButtonProps extends ComponentProps {
|
|
|
71
71
|
*/
|
|
72
72
|
click?: EventCallback<EvClick>;
|
|
73
73
|
|
|
74
|
+
/**
|
|
75
|
+
* A menu that a click opens under the button, in place of the click event.
|
|
76
|
+
* A function is called at each click: it gives the items of that time.
|
|
77
|
+
* The button gets the class "with-menu".
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* new Button( { label: "File", menu: [ { text: "Open", click: open }, "-", { text: "Quit", click: quit } ] } );
|
|
81
|
+
*/
|
|
74
82
|
menu?: MenuElement[] | (( ) => MenuElement[]);
|
|
75
83
|
}
|
|
76
84
|
|
|
@@ -90,7 +98,19 @@ export interface ButtonProps extends ComponentProps {
|
|
|
90
98
|
* --button-background-disabled
|
|
91
99
|
* --button-color-disabled
|
|
92
100
|
* --button-icon-color
|
|
101
|
+
* --ol-button-background
|
|
102
|
+
* --ol-button-color
|
|
103
|
+
* --ol-button-border
|
|
104
|
+
* --ol-button-icon-color
|
|
105
|
+
* --ol-button-background-hover
|
|
106
|
+
* --ol-button-color-hover
|
|
107
|
+
* --ol-button-background-active
|
|
108
|
+
* --ol-button-color-active
|
|
109
|
+
* --ol-button-color-disabled
|
|
110
|
+
* --ol-button-border-focus
|
|
111
|
+
* --ol-button-color-focus
|
|
93
112
|
* ```
|
|
113
|
+
* the --ol-button-* variables are the ones of the outline buttons
|
|
94
114
|
*/
|
|
95
115
|
|
|
96
116
|
@class_ns( "x4" )
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
--calendar-header-color: var( --text-primary );
|
|
38
38
|
--calendar-out-color: var( --disabled-color-dark );
|
|
39
|
+
--calendar-day-color: var( --text-primary );
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
.x4calendar {
|
|
@@ -93,7 +94,7 @@
|
|
|
93
94
|
min-width: 28px;
|
|
94
95
|
min-height: 28px;
|
|
95
96
|
|
|
96
|
-
color: var( --
|
|
97
|
+
color: var( --calendar-day-color );
|
|
97
98
|
text-align: center;
|
|
98
99
|
|
|
99
100
|
.text {
|
|
@@ -54,7 +54,7 @@ interface CalendarProps extends ComponentProps {
|
|
|
54
54
|
* ```
|
|
55
55
|
* --calendar-btn-background
|
|
56
56
|
* --calendar-btn-color
|
|
57
|
-
* --calendar-btn-color
|
|
57
|
+
* --calendar-btn-color-hover
|
|
58
58
|
* --calendar-week-color
|
|
59
59
|
* --calendar-week-color-hover
|
|
60
60
|
* --calendard-day-background-hover
|
|
@@ -66,6 +66,7 @@ interface CalendarProps extends ComponentProps {
|
|
|
66
66
|
* --calendar-today-border
|
|
67
67
|
* --calendar-header-color
|
|
68
68
|
* --calendar-out-color
|
|
69
|
+
* --calendar-day-color
|
|
69
70
|
* ```
|
|
70
71
|
*/
|
|
71
72
|
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
17
|
:root {
|
|
18
|
-
--chart-background:
|
|
19
|
-
--chart-text:
|
|
20
|
-
--chart-grid:
|
|
21
|
-
--chart-axis:
|
|
18
|
+
--chart-background: var( --background-primary );
|
|
19
|
+
--chart-text: var( --text-ternary );
|
|
20
|
+
--chart-grid: var( --border );
|
|
21
|
+
--chart-axis: var( --border-hover );
|
|
22
22
|
|
|
23
23
|
// series colors, used in this order
|
|
24
24
|
--chart-color-1: #2a78d6;
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
--checkbox-color-disabled: var( --disabled-background );
|
|
25
25
|
--checkbox-check-border: var( --border );
|
|
26
26
|
--checkbox-check-border-hover: var( --border-hover );
|
|
27
|
+
--checkbox-check-color: var( --accent-color );
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
.x4checkbox {
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
.inner {
|
|
42
43
|
height: 1rem;
|
|
43
44
|
width: 1rem;
|
|
44
|
-
color:
|
|
45
|
+
color: var( --checkbox-check-color );
|
|
45
46
|
position: relative;
|
|
46
47
|
order: 1;
|
|
47
48
|
|
|
@@ -74,7 +74,6 @@
|
|
|
74
74
|
overflow: hidden;
|
|
75
75
|
|
|
76
76
|
background-image: linear-gradient(to right, rgb(255, 0, 0), rgb(255, 255, 0), rgb(0, 255, 0), rgb(0, 255, 212), rgb(0, 0, 255), rgb(255, 0, 255), rgb(255, 0, 0));
|
|
77
|
-
border: 1px solid var( --color-gray-3 );
|
|
78
77
|
|
|
79
78
|
.thumb {
|
|
80
79
|
@include overlay-shadow;
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
:root {
|
|
20
20
|
--color-dialog-caption: var( --color-primary-a80 );
|
|
21
21
|
--color-dialog-caption-text: var( --color-primary-a0 );
|
|
22
|
+
--color-dialog-background: var( --background-primary );
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
.x4dialog {
|
|
@@ -26,8 +27,7 @@
|
|
|
26
27
|
@extend %vbox;
|
|
27
28
|
|
|
28
29
|
position: absolute !important;
|
|
29
|
-
background-color:
|
|
30
|
-
border: 1px solid var( --border-dark );
|
|
30
|
+
background-color: var( --color-dialog-background );
|
|
31
31
|
max-width: 99vw;
|
|
32
32
|
outline: none;
|
|
33
33
|
|
|
@@ -15,13 +15,14 @@
|
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
17
|
.x4dockingview {
|
|
18
|
-
--dock-line: var( --border
|
|
19
|
-
--dock-title-background: var( --background-secondary
|
|
20
|
-
--dock-title-background-hover:
|
|
21
|
-
--dock-title-color: var( --text-ternary
|
|
22
|
-
--dock-title-color-active: var( --text-primary
|
|
23
|
-
--dock-accent: var( --accent-background
|
|
24
|
-
--dock-
|
|
18
|
+
--dock-line: var( --border ); // between two panels, under a title
|
|
19
|
+
--dock-title-background: var( --background-secondary );
|
|
20
|
+
--dock-title-background-hover: var( --accent-background-light );
|
|
21
|
+
--dock-title-color: var( --text-ternary );
|
|
22
|
+
--dock-title-color-active: var( --text-primary );
|
|
23
|
+
--dock-accent: var( --accent-background ); // the tab in front, the sizer under the pointer, the border of the preview
|
|
24
|
+
--dock-preview-background: var( --accent-background-light ); // where the panel that is dragged will go
|
|
25
|
+
--dock-float-background: var( --background-primary );
|
|
25
26
|
--dock-float-shadow: 0 6px 24px rgba( 0, 0, 0, 0.35 );
|
|
26
27
|
|
|
27
28
|
position: relative;
|
|
@@ -279,7 +280,7 @@
|
|
|
279
280
|
box-sizing: border-box;
|
|
280
281
|
pointer-events: none;
|
|
281
282
|
|
|
282
|
-
background:
|
|
283
|
+
background: var( --dock-preview-background );
|
|
283
284
|
border: 1px solid var( --dock-accent );
|
|
284
285
|
border-radius: 3px;
|
|
285
286
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
@use "../shared.scss";
|
|
18
18
|
|
|
19
19
|
:root {
|
|
20
|
-
--form
|
|
20
|
+
--form-background: transparent;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
.x4form {
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
@extend %flex;
|
|
26
26
|
|
|
27
27
|
padding: 16px;
|
|
28
|
-
background-color: var( --
|
|
28
|
+
background-color: var( --form-background );
|
|
29
29
|
|
|
30
30
|
&.horizontal {
|
|
31
31
|
flex-direction: row;
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
17
|
:root {
|
|
18
|
-
--input-background:
|
|
19
|
-
--input-color:
|
|
18
|
+
--input-background: var( --background-input );
|
|
19
|
+
--input-color: var( --text-primary );
|
|
20
20
|
|
|
21
21
|
--input-sel-background: var( --accent-background );
|
|
22
22
|
--input-sel-color: var( --accent-color );
|
|
@@ -28,9 +28,12 @@
|
|
|
28
28
|
--listbox-item-color-hover: var( --text-primary );;
|
|
29
29
|
--listbox-item-background-hover: var( --background-secondary );
|
|
30
30
|
|
|
31
|
-
--listbox-background:
|
|
31
|
+
--listbox-background: var( --background-primary );
|
|
32
32
|
--listbox-border: var( --border );
|
|
33
33
|
--listbox-border-focus: var( --accent-background-focus );
|
|
34
|
+
|
|
35
|
+
--listbox-title-background: var( --background-primary );
|
|
36
|
+
--listbox-title-color: var( --text-primary );
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
.x4listbox {
|
|
@@ -48,10 +51,10 @@
|
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
&>.title {
|
|
51
|
-
background:
|
|
54
|
+
background: var( --listbox-title-background );
|
|
52
55
|
padding: 4px;
|
|
53
56
|
font-weight: bold;
|
|
54
|
-
color:
|
|
57
|
+
color: var( --listbox-title-color );
|
|
55
58
|
border-bottom: 1px solid var(--border);
|
|
56
59
|
}
|
|
57
60
|
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
@use "../shared.scss";
|
|
18
18
|
|
|
19
19
|
:root {
|
|
20
|
-
--menu-background:
|
|
20
|
+
--menu-background: var( --background-primary );
|
|
21
21
|
--menu-border: var( --border-hover );
|
|
22
22
|
|
|
23
23
|
--menuitem-color: var( --text-ternary );;
|
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
position: absolute;
|
|
34
34
|
overflow-y: auto;
|
|
35
35
|
|
|
36
|
-
border-radius: var(--bradius);
|
|
37
36
|
padding: 8px 0;
|
|
38
37
|
min-width: 150px;
|
|
39
38
|
|
|
@@ -20,12 +20,16 @@
|
|
|
20
20
|
--msgbox-caption-color: var( --alert-color );
|
|
21
21
|
|
|
22
22
|
--msgbox-icon-color: var( --alert-background );
|
|
23
|
+
--msgbox-question-icon-color: var( --accent-background ); // a question, an InputBox, a PromptBox
|
|
24
|
+
|
|
25
|
+
--msgbox-log-background: var( --background-ternary ); // the lines of a ProgressionBox
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
.x4messagebox {
|
|
26
29
|
max-width: 60vw;
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
// an error has its own title bar; a question has the one of a Dialog
|
|
32
|
+
&.error > .caption {
|
|
29
33
|
background-color: var( --msgbox-caption-background );
|
|
30
34
|
|
|
31
35
|
& > #title {
|
|
@@ -45,24 +49,20 @@
|
|
|
45
49
|
line-height: 1.8em;
|
|
46
50
|
}
|
|
47
51
|
}
|
|
52
|
+
|
|
53
|
+
&.question .x4form .x4icon {
|
|
54
|
+
color: var( --msgbox-question-icon-color );
|
|
55
|
+
}
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
.x4inputbox,
|
|
51
59
|
.x4promptbox {
|
|
52
60
|
max-width: 60vw;
|
|
53
61
|
|
|
54
|
-
& > .caption {
|
|
55
|
-
background-color: var( --msgbox-caption-background );
|
|
56
|
-
|
|
57
|
-
& > #title {
|
|
58
|
-
color: var( --msgbox-caption-color );
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
62
|
& .x4form {
|
|
63
63
|
min-width: 400px;
|
|
64
64
|
.x4icon {
|
|
65
|
-
color: var( --msgbox-icon-color );
|
|
65
|
+
color: var( --msgbox-question-icon-color );
|
|
66
66
|
height: 64px;
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
flex-grow: 1;
|
|
135
135
|
max-height: 400px;
|
|
136
136
|
overflow: auto;
|
|
137
|
-
background-color:
|
|
137
|
+
background-color: var( --msgbox-log-background );
|
|
138
138
|
padding: 4px 8px;
|
|
139
139
|
margin: 0 16px;
|
|
140
140
|
|
|
@@ -34,7 +34,11 @@ export interface MessageBoxProps extends DialogProps {
|
|
|
34
34
|
* --msgbox-caption-background
|
|
35
35
|
* --msgbox-caption-color
|
|
36
36
|
* --msgbox-icon-color
|
|
37
|
+
* --msgbox-question-icon-color
|
|
38
|
+
* --msgbox-log-background
|
|
37
39
|
* ```
|
|
40
|
+
* --msgbox-caption-* and --msgbox-icon-color are the ones of an error; a question, an InputBox
|
|
41
|
+
* and a PromptBox have the title bar of a Dialog and their icon in --msgbox-question-icon-color
|
|
38
42
|
*/
|
|
39
43
|
|
|
40
44
|
@class_ns( "x4" )
|
|
@@ -58,7 +62,9 @@ export class MessageBox extends Dialog<DialogProps>
|
|
|
58
62
|
}
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
|
|
65
|
+
// the kind as a class: an error has its own title bar
|
|
66
|
+
const box = new MessageBox({
|
|
67
|
+
cls: icon_type ?? "error",
|
|
62
68
|
modal: true,
|
|
63
69
|
title: title ?? _tr.global.error,
|
|
64
70
|
movable: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--!Font Awesome Pro 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc.--><path class="fa-secondary" opacity=".4" d="M0 128l32 0 224 0 32 0 0 64-32 0L64 192l0 256 448 0 0-128 0-32 64 0 0 32 0 160 0 32-32 0L32 512 0 512l0-32L0 160l0-32z"/><path class="fa-primary" d="M288 352l16-112L468.7 75.3l96 96L400 336 288 352zM587.3 148.7l-96-96L544 0l96 96-52.7 52.7zM96 288l64 0 0 64-64 0 0-64zm160 0l0 64-64 0 0-64 64 0z"/></svg>
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512" fill="currentColor"><!--!Font Awesome Pro 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2024 Fonticons, Inc.--><path class="fa-secondary" opacity=".4" d="M0 128l32 0 224 0 32 0 0 64-32 0L64 192l0 256 448 0 0-128 0-32 64 0 0 32 0 160 0 32-32 0L32 512 0 512l0-32L0 160l0-32z"/><path class="fa-primary" d="M288 352l16-112L468.7 75.3l96 96L400 336 288 352zM587.3 148.7l-96-96L544 0l96 96-52.7 52.7zM96 288l64 0 0 64-64 0 0-64zm160 0l0 64-64 0 0-64 64 0z"/></svg>
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
|
|
19
19
|
:root {
|
|
20
20
|
--panel-border: var( --border );
|
|
21
|
-
--panel-title-color: var( --
|
|
21
|
+
--panel-title-color: var( --text-primary );
|
|
22
|
+
--panel-title-background: var( --background-primary );
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
|
|
@@ -34,9 +35,9 @@
|
|
|
34
35
|
position: absolute;
|
|
35
36
|
left: 4px;
|
|
36
37
|
top: -0.7em;
|
|
37
|
-
background-color:
|
|
38
|
+
background-color: var( --panel-title-background );
|
|
38
39
|
font-weight: bold;
|
|
39
|
-
color: var(--
|
|
40
|
+
color: var( --panel-title-color );
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
& > .body {
|
|
@@ -16,15 +16,14 @@
|
|
|
16
16
|
|
|
17
17
|
:root {
|
|
18
18
|
--modal-mask-background: rgb(0 0 0 / 60% );
|
|
19
|
+
--popup-background: transparent;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
.x4popup {
|
|
22
23
|
position: absolute !important;
|
|
23
|
-
background-color: var(--
|
|
24
|
-
border: 1px solid var(--border-color);
|
|
24
|
+
background-color: var( --popup-background );
|
|
25
25
|
overflow: hidden;
|
|
26
26
|
z-index: 1000;
|
|
27
|
-
border-radius: var(--bradius);
|
|
28
27
|
|
|
29
28
|
&.popup-caption,
|
|
30
29
|
.popup-caption {
|
|
@@ -5,16 +5,16 @@
|
|
|
5
5
|
**/
|
|
6
6
|
|
|
7
7
|
:root {
|
|
8
|
-
--propertygrid-background:
|
|
9
|
-
--propertygrid-gadget-background:
|
|
10
|
-
--propertygrid-gadget-color:
|
|
8
|
+
--propertygrid-background: var( --background-primary );
|
|
9
|
+
--propertygrid-gadget-background: var( --background-primary );
|
|
10
|
+
--propertygrid-gadget-color: var( --text-primary );
|
|
11
11
|
|
|
12
12
|
--propertygrid-odd-background: var(--color-primary-a5);
|
|
13
13
|
--propertygrid-even-background: transparent;
|
|
14
14
|
--propertygrid-disabled-background: rgb(170 170 170 / 14%);
|
|
15
15
|
--propertygrid-hover-background: var(--color-primary-a10);
|
|
16
16
|
--propertygrid-focus-background: var(--color-primary-a20);
|
|
17
|
-
--propertygrid-input-background:
|
|
17
|
+
--propertygrid-input-background: var( --background-input );
|
|
18
18
|
|
|
19
19
|
--propertygrid-group-background: var( --color-primary-a5 );
|
|
20
20
|
--propertygrid-group-color: var( --color-primary-a50 );
|
|
@@ -14,6 +14,12 @@
|
|
|
14
14
|
* that can be found in the LICENSE file or at https://opensource.org/licenses/MIT.
|
|
15
15
|
**/
|
|
16
16
|
|
|
17
|
+
:root {
|
|
18
|
+
--radio-background: var( --background-primary );
|
|
19
|
+
--radio-check-color: var( --accent-color );
|
|
20
|
+
--radio-square-border-checked: var( --accent-color );
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
.x4radio {
|
|
18
24
|
display: flex;
|
|
19
25
|
flex-direction: row;
|
|
@@ -36,7 +42,7 @@
|
|
|
36
42
|
input {
|
|
37
43
|
appearance: none;
|
|
38
44
|
border-radius: 50%;
|
|
39
|
-
background-color:
|
|
45
|
+
background-color: var( --radio-background );
|
|
40
46
|
cursor: pointer;
|
|
41
47
|
display: block;
|
|
42
48
|
|
|
@@ -67,7 +73,7 @@
|
|
|
67
73
|
}
|
|
68
74
|
|
|
69
75
|
.fa-secondary {
|
|
70
|
-
fill:
|
|
76
|
+
fill: var( --radio-check-color );
|
|
71
77
|
}
|
|
72
78
|
}
|
|
73
79
|
|
|
@@ -157,7 +163,7 @@
|
|
|
157
163
|
|
|
158
164
|
&:has(input:checked) {
|
|
159
165
|
background-color: var( --accent-background-active );
|
|
160
|
-
border-color:
|
|
166
|
+
border-color: var( --radio-square-border-checked );
|
|
161
167
|
font-weight: 700;
|
|
162
168
|
}
|
|
163
169
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
:root {
|
|
3
|
+
--select-border: var( --border );
|
|
4
|
+
--select-border-focus: var( --accent-background );
|
|
5
|
+
--select-background: var( --background-primary );
|
|
6
|
+
--select-color: var( --text-primary );
|
|
7
|
+
--select-arrow-color: var( --text-ternary );
|
|
8
|
+
}
|
|
8
9
|
|
|
9
10
|
.x4select,
|
|
10
11
|
::picker(select) {
|
|
@@ -14,22 +15,26 @@
|
|
|
14
15
|
outline: none;
|
|
15
16
|
|
|
16
17
|
border-radius: 0;
|
|
17
|
-
border: 1px solid var( --select-border
|
|
18
|
-
background-color: var( --select-background
|
|
18
|
+
border: 1px solid var( --select-border );
|
|
19
|
+
background-color: var( --select-background );
|
|
20
|
+
color: var( --select-color );
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
.x4select {
|
|
22
24
|
appearance: none;
|
|
23
25
|
-webkit-appearance: none;
|
|
24
26
|
-moz-appearance: none;
|
|
25
|
-
|
|
27
|
+
// the arrow: two halves of a square side by side, in the colour of the variable
|
|
28
|
+
background-image:
|
|
29
|
+
linear-gradient( 45deg, transparent 50%, var( --select-arrow-color ) 50% ),
|
|
30
|
+
linear-gradient( 135deg, var( --select-arrow-color ) 50%, transparent 50% );
|
|
26
31
|
background-repeat: no-repeat;
|
|
27
|
-
background-position: right
|
|
28
|
-
background-size:
|
|
32
|
+
background-position: right 13px center, right 8px center;
|
|
33
|
+
background-size: 5px 5px, 5px 5px;
|
|
29
34
|
padding-right: 23px;
|
|
30
35
|
|
|
31
36
|
&:focus-visible {
|
|
32
|
-
border-color: var( --select-border-focus
|
|
37
|
+
border-color: var( --select-border-focus );
|
|
33
38
|
}
|
|
34
39
|
|
|
35
40
|
.select-option {
|
|
@@ -46,6 +46,15 @@ interface SelectEvents extends ComponentEvents {
|
|
|
46
46
|
/**
|
|
47
47
|
* simple select
|
|
48
48
|
* cf. Combobox
|
|
49
|
+
*
|
|
50
|
+
* @cssvar
|
|
51
|
+
* ```
|
|
52
|
+
* --select-border
|
|
53
|
+
* --select-border-focus
|
|
54
|
+
* --select-background
|
|
55
|
+
* --select-color
|
|
56
|
+
* --select-arrow-color
|
|
57
|
+
* ```
|
|
49
58
|
*/
|
|
50
59
|
|
|
51
60
|
@class_ns( "x4" )
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
--settingsview-toc-width: 210px;
|
|
19
19
|
--settingsview-section-background: var( --color-primary-a10 );
|
|
20
20
|
--settingsview-section-title-background: var( --color-primary-a20 );
|
|
21
|
-
--settingsview-hover-background:
|
|
21
|
+
--settingsview-hover-background: var( --color-primary-a20 );
|
|
22
22
|
--settingsview-marker: var( --accent-background );
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -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 {
|
package/src/core/core_colors.ts
CHANGED
|
@@ -26,6 +26,34 @@ function round(v: number) {
|
|
|
26
26
|
return Math.round(v);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
let ctx2d: CanvasRenderingContext2D = null;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* a colour of css as the browser paints it: [red, green, blue, alpha 0-1];
|
|
33
|
+
* null when the browser does not know it
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
function browserColor( value: string ) {
|
|
37
|
+
if( !ctx2d ) {
|
|
38
|
+
const canvas = document.createElement( "canvas" );
|
|
39
|
+
canvas.width = canvas.height = 1;
|
|
40
|
+
ctx2d = canvas.getContext( "2d", { willReadFrequently: true } );
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// a value the canvas refuses leaves fillStyle as it was
|
|
44
|
+
ctx2d.fillStyle = "#010203";
|
|
45
|
+
ctx2d.fillStyle = value;
|
|
46
|
+
if( ctx2d.fillStyle=="#010203" ) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// fillStyle keeps the colour as it was written (oklch, color(srgb ...)): the pixel is in rgb
|
|
51
|
+
ctx2d.clearRect( 0, 0, 1, 1 );
|
|
52
|
+
ctx2d.fillRect( 0, 0, 1, 1 );
|
|
53
|
+
const px = ctx2d.getImageData( 0, 0, 1, 1 ).data;
|
|
54
|
+
return [ px[0], px[1], px[2], px[3] / 255 ];
|
|
55
|
+
}
|
|
56
|
+
|
|
29
57
|
|
|
30
58
|
export interface Rgb {
|
|
31
59
|
red: number;
|
|
@@ -79,6 +107,7 @@ export class Color {
|
|
|
79
107
|
* var( --color-5 )
|
|
80
108
|
* cyan
|
|
81
109
|
* transparent
|
|
110
|
+
* any other colour of css the browser knows: hsl( ), oklch( ), color-mix( )...
|
|
82
111
|
*/
|
|
83
112
|
|
|
84
113
|
setValue(value: string): this {
|
|
@@ -137,6 +166,12 @@ export class Color {
|
|
|
137
166
|
}
|
|
138
167
|
}
|
|
139
168
|
|
|
169
|
+
// another colour the browser knows (color-mix, hsl, oklch...)
|
|
170
|
+
const known = browserColor( value );
|
|
171
|
+
if( known ) {
|
|
172
|
+
return this.setRgb( known[0], known[1], known[2], known[3] );
|
|
173
|
+
}
|
|
174
|
+
|
|
140
175
|
// red, to be seen, and marked as invalid
|
|
141
176
|
this.setRgb(255, 0, 0, 1);
|
|
142
177
|
this.invalid = true;
|
|
@@ -343,32 +378,92 @@ export class Color {
|
|
|
343
378
|
* @param percent - The percentage to lighten (0-100).
|
|
344
379
|
* @returns The current Color instance.
|
|
345
380
|
*/
|
|
346
|
-
lighten(percent: number)
|
|
381
|
+
lighten(percent: number): this {
|
|
382
|
+
const factor = clamp(percent, 0, 100) / 100;
|
|
347
383
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
else if (percent > 100) {
|
|
352
|
-
percent = 100;
|
|
353
|
-
}
|
|
384
|
+
const [r, g, b, a] = this.rgb;
|
|
385
|
+
this.rgb = [round(r + (255 - r) * factor), round(g + (255 - g) * factor), round(b + (255 - b) * factor), a];
|
|
354
386
|
|
|
355
|
-
|
|
387
|
+
return this;
|
|
388
|
+
}
|
|
356
389
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
390
|
+
/**
|
|
391
|
+
* Darkens the color by a given percentage.
|
|
392
|
+
*
|
|
393
|
+
* @param percent - The percentage to darken (0-100).
|
|
394
|
+
* @returns The current Color instance.
|
|
395
|
+
*/
|
|
396
|
+
darken(percent: number): this {
|
|
397
|
+
const factor = 1 - clamp(percent, 0, 100) / 100;
|
|
364
398
|
|
|
365
|
-
const
|
|
366
|
-
this.rgb = [
|
|
399
|
+
const [r, g, b, a] = this.rgb;
|
|
400
|
+
this.rgb = [round(r * factor), round(g * factor), round(b * factor), a];
|
|
367
401
|
|
|
368
402
|
return this;
|
|
369
403
|
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Mixes the color with another one, alpha included.
|
|
407
|
+
*
|
|
408
|
+
* @param other - The other color.
|
|
409
|
+
* @param amount - The part of the other color (0-1): 0 keeps this color, 1 gives the other one.
|
|
410
|
+
* @returns The current Color instance.
|
|
411
|
+
*/
|
|
412
|
+
mix(other: Color, amount: number): this {
|
|
413
|
+
const t = clamp(amount, 0, 1);
|
|
414
|
+
|
|
415
|
+
const [r, g, b, a] = this.rgb;
|
|
416
|
+
const [r2, g2, b2, a2] = other.rgb;
|
|
417
|
+
this.rgb = [round(r + (r2 - r) * t), round(g + (g2 - g) * t), round(b + (b2 - b) * t), a + (a2 - a) * t];
|
|
418
|
+
|
|
419
|
+
return this;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Gets the relative luminance of the color, as WCAG defines it. The alpha is not used.
|
|
424
|
+
*
|
|
425
|
+
* @returns The luminance (0 for black, 1 for white).
|
|
426
|
+
*/
|
|
427
|
+
luminance(): number {
|
|
428
|
+
// the components in linear light
|
|
429
|
+
const lin = (v: number) => {
|
|
430
|
+
v /= 255;
|
|
431
|
+
return v <= 0.04045 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const [r, g, b] = this.rgb;
|
|
435
|
+
return 0.2126 * lin(r) + 0.7152 * lin(g) + 0.0722 * lin(b);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* Gets the contrast ratio between the color and another one, as WCAG defines it.
|
|
440
|
+
*
|
|
441
|
+
* @param other - The other color.
|
|
442
|
+
* @returns The ratio (1 for the same luminance, 21 for black and white).
|
|
443
|
+
*/
|
|
444
|
+
contrast(other: Color): number {
|
|
445
|
+
const l1 = this.luminance();
|
|
446
|
+
const l2 = other.luminance();
|
|
447
|
+
return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Gets, of two colors of text, the one that contrasts most with the color.
|
|
452
|
+
*
|
|
453
|
+
* @param light - The light text color (white by default).
|
|
454
|
+
* @param dark - The dark text color (black by default).
|
|
455
|
+
* @returns A copy of light or dark.
|
|
456
|
+
*/
|
|
457
|
+
textColor(light = WHITE, dark = BLACK): Color {
|
|
458
|
+
const best = this.contrast(light) >= this.contrast(dark) ? light : dark;
|
|
459
|
+
|
|
460
|
+
const [r, g, b, a] = best.rgb;
|
|
461
|
+
return new Color(r, g, b, a);
|
|
462
|
+
}
|
|
370
463
|
}
|
|
371
464
|
|
|
465
|
+
const WHITE = new Color(255, 255, 255);
|
|
466
|
+
const BLACK = new Color(0, 0, 0);
|
|
372
467
|
|
|
373
468
|
|
|
374
469
|
|