kempo-testing-framework 1.2.4 → 1.3.3
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/.github/copilot-instructions.md +105 -105
- package/.github/workflows/publish-npm.yml +29 -0
- package/CONTRIBUTING.md +107 -107
- package/gui/components/Collapsible.js +54 -54
- package/gui/components/Icon.js +151 -151
- package/gui/components/Logs.js +73 -73
- package/gui/components/SettingCheckbox.js +42 -42
- package/gui/components/SettingNumber.js +77 -77
- package/gui/components/SettingSelect.js +67 -67
- package/gui/components/TestFramework.js +378 -378
- package/gui/components/TestSuite.js +181 -181
- package/gui/components/TestSummary.js +189 -189
- package/gui/components/Theme.js +40 -40
- package/gui/components/settingsStore.js +46 -46
- package/gui/icons/fail.svg +1 -1
- package/gui/icons/pass.svg +1 -1
- package/gui/icons/running.svg +1 -1
- package/gui/icons/settings.svg +1 -1
- package/package.json +6 -1
- package/src/browserTestServer.js +115 -115
- package/src/cli.js +198 -198
- package/src/gui.js +15 -2
- package/src/runBrowserTests.js +87 -87
- package/src/runTestFiles.js +94 -94
- package/src/runTests.js +83 -83
- package/src/utils/logLevels.js +7 -7
- package/test.html +30 -30
- package/tests/Counter.js +33 -33
- package/tests/cli-flags.node-test.js +54 -54
- package/tests/cli-help.node-test.js +61 -61
- package/tests/cli-loglevel.node-test.js +40 -40
- package/tests/collapsible.browser-test.js +49 -49
- package/tests/counter.browser-test.js +140 -140
- package/tests/example.node-test.js +103 -103
- package/tests/fibonacci.js +92 -92
- package/tests/fibonacci.test.js +285 -285
- package/tests/icon.browser-test.js +54 -54
- package/tests/logs.browser-test.js +47 -47
- package/tests/setting-checkbox.browser-test.js +48 -48
- package/tests/setting-number.browser-test.js +54 -54
- package/tests/setting-select.browser-test.js +47 -47
- package/tests/settings-store.browser-test.js +26 -26
- package/tests/src-browserTestServer.node-test.js +47 -47
- package/tests/src-cli.node-test.js +32 -32
- package/tests/src-findTests.node-test.js +41 -41
- package/tests/src-logLevels.node-test.js +29 -29
- package/tests/src-runBrowserTests.node-test.js +41 -41
- package/tests/src-runTestFiles.node-test.js +42 -42
- package/tests/src-runTests.node-test.js +56 -56
- package/tests/test-framework.browser-test.js +65 -65
- package/tests/test-summary.browser-test.js +78 -78
- package/tests/test.browser-test.js +56 -56
- package/tests/testfile.browser-test.js +60 -60
- package/tests/theme.browser-test.js +38 -38
package/gui/components/Icon.js
CHANGED
|
@@ -1,151 +1,151 @@
|
|
|
1
|
-
import { LitElement, html, css, unsafeHTML } from '../lit-all.min.js';
|
|
2
|
-
|
|
3
|
-
// Static cache to store fetched icons across all instances
|
|
4
|
-
const iconCache = new Map();
|
|
5
|
-
|
|
6
|
-
window.customElements.define('ktf-icon', class extends LitElement {
|
|
7
|
-
/*
|
|
8
|
-
Properties
|
|
9
|
-
*/
|
|
10
|
-
static properties = {
|
|
11
|
-
name: { type: String, reflect: true },
|
|
12
|
-
svg: { type: String },
|
|
13
|
-
animation: { type: String, reflect: true }
|
|
14
|
-
}
|
|
15
|
-
constructor(){
|
|
16
|
-
super();
|
|
17
|
-
this.name = '';
|
|
18
|
-
this.animation = 'none';
|
|
19
|
-
this.defaultSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960""><path fill="currentColor" d="M480-79q-16 0-30.5-6T423-102L102-423q-11-12-17-26.5T79-480q0-16 6-31t17-26l321-321q12-12 26.5-17.5T480-881q16 0 31 5.5t26 17.5l321 321q12 11 17.5 26t5.5 31q0 16-5.5 30.5T858-423L537-102q-11 11-26 17t-31 6Zm0-80 321-321-321-321-321 321 321 321Zm-40-281h80v-240h-80v240Zm40 120q17 0 28.5-11.5T520-360q0-17-11.5-28.5T480-400q-17 0-28.5 11.5T440-360q0 17 11.5 28.5T480-320Zm0-160Z"/></svg>';
|
|
20
|
-
this.svg = this.defaultSvg;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/*
|
|
24
|
-
Lifecycle Callback
|
|
25
|
-
*/
|
|
26
|
-
updated(changedProperties){
|
|
27
|
-
if(changedProperties.has('name')){
|
|
28
|
-
this.fetchIcon();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/*
|
|
33
|
-
Methods
|
|
34
|
-
*/
|
|
35
|
-
async fetchIcon(){
|
|
36
|
-
if (this.name) {
|
|
37
|
-
// Check cache first
|
|
38
|
-
const cached = iconCache.get(this.name);
|
|
39
|
-
if (cached) {
|
|
40
|
-
if (cached instanceof Promise) {
|
|
41
|
-
this.svg = await cached;
|
|
42
|
-
} else {
|
|
43
|
-
this.svg = cached;
|
|
44
|
-
}
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Cache the promise immediately
|
|
49
|
-
const promise = (async () => {
|
|
50
|
-
try {
|
|
51
|
-
const response = await fetch(`/icons/${this.name}.svg`);
|
|
52
|
-
return response.ok ? await response.text() : this.defaultSvg;
|
|
53
|
-
} catch {
|
|
54
|
-
return this.defaultSvg;
|
|
55
|
-
}
|
|
56
|
-
})();
|
|
57
|
-
|
|
58
|
-
iconCache.set(this.name, promise);
|
|
59
|
-
|
|
60
|
-
const svgContent = await promise;
|
|
61
|
-
iconCache.set(this.name, svgContent);
|
|
62
|
-
this.svg = svgContent;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/*
|
|
67
|
-
Rendering
|
|
68
|
-
*/
|
|
69
|
-
render(){
|
|
70
|
-
return html`${unsafeHTML(this.svg)}`;
|
|
71
|
-
}
|
|
72
|
-
static styles = css`
|
|
73
|
-
:host {
|
|
74
|
-
display: inline-block;
|
|
75
|
-
height: 1.35em;
|
|
76
|
-
width: 1.35em;
|
|
77
|
-
vertical-align: top;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/* Animation classes */
|
|
81
|
-
:host([animation="spin"]) {
|
|
82
|
-
animation: spin 1s linear infinite;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
:host([animation="pulse"]) {
|
|
86
|
-
animation: pulse 1.5s ease-in-out infinite;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
:host([animation="bounce"]) {
|
|
90
|
-
animation: bounce 1s ease-in-out infinite;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
:host([animation="shake"]) {
|
|
94
|
-
animation: shake 0.5s ease-in-out infinite;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
:host([animation="fade"]) {
|
|
98
|
-
animation: fade 2s ease-in-out infinite;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
:host([animation="flip"]) {
|
|
102
|
-
animation: flip 2s ease-in-out infinite;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/* Keyframe definitions */
|
|
106
|
-
@keyframes spin {
|
|
107
|
-
from { transform: rotate(0deg); }
|
|
108
|
-
to { transform: rotate(360deg); }
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
@keyframes pulse {
|
|
112
|
-
0%, 100% {
|
|
113
|
-
transform: scale(1);
|
|
114
|
-
opacity: 1;
|
|
115
|
-
}
|
|
116
|
-
50% {
|
|
117
|
-
transform: scale(1.1);
|
|
118
|
-
opacity: 0.7;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
@keyframes bounce {
|
|
123
|
-
0%, 20%, 50%, 80%, 100% {
|
|
124
|
-
transform: translateY(0);
|
|
125
|
-
}
|
|
126
|
-
40% {
|
|
127
|
-
transform: translateY(-0.3em);
|
|
128
|
-
}
|
|
129
|
-
60% {
|
|
130
|
-
transform: translateY(-0.15em);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
@keyframes shake {
|
|
135
|
-
0%, 100% { transform: translateX(0); }
|
|
136
|
-
10%, 30%, 50%, 70%, 90% { transform: translateX(-0.1em); }
|
|
137
|
-
20%, 40%, 60%, 80% { transform: translateX(0.1em); }
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
@keyframes fade {
|
|
141
|
-
0%, 100% { opacity: 1; }
|
|
142
|
-
50% { opacity: 0.3; }
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
@keyframes flip {
|
|
146
|
-
0% { transform: rotateY(0deg); }
|
|
147
|
-
50% { transform: rotateY(180deg); }
|
|
148
|
-
100% { transform: rotateY(360deg); }
|
|
149
|
-
}
|
|
150
|
-
`
|
|
151
|
-
});
|
|
1
|
+
import { LitElement, html, css, unsafeHTML } from '../lit-all.min.js';
|
|
2
|
+
|
|
3
|
+
// Static cache to store fetched icons across all instances
|
|
4
|
+
const iconCache = new Map();
|
|
5
|
+
|
|
6
|
+
window.customElements.define('ktf-icon', class extends LitElement {
|
|
7
|
+
/*
|
|
8
|
+
Properties
|
|
9
|
+
*/
|
|
10
|
+
static properties = {
|
|
11
|
+
name: { type: String, reflect: true },
|
|
12
|
+
svg: { type: String },
|
|
13
|
+
animation: { type: String, reflect: true }
|
|
14
|
+
}
|
|
15
|
+
constructor(){
|
|
16
|
+
super();
|
|
17
|
+
this.name = '';
|
|
18
|
+
this.animation = 'none';
|
|
19
|
+
this.defaultSvg = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960""><path fill="currentColor" d="M480-79q-16 0-30.5-6T423-102L102-423q-11-12-17-26.5T79-480q0-16 6-31t17-26l321-321q12-12 26.5-17.5T480-881q16 0 31 5.5t26 17.5l321 321q12 11 17.5 26t5.5 31q0 16-5.5 30.5T858-423L537-102q-11 11-26 17t-31 6Zm0-80 321-321-321-321-321 321 321 321Zm-40-281h80v-240h-80v240Zm40 120q17 0 28.5-11.5T520-360q0-17-11.5-28.5T480-400q-17 0-28.5 11.5T440-360q0 17 11.5 28.5T480-320Zm0-160Z"/></svg>';
|
|
20
|
+
this.svg = this.defaultSvg;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
Lifecycle Callback
|
|
25
|
+
*/
|
|
26
|
+
updated(changedProperties){
|
|
27
|
+
if(changedProperties.has('name')){
|
|
28
|
+
this.fetchIcon();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
Methods
|
|
34
|
+
*/
|
|
35
|
+
async fetchIcon(){
|
|
36
|
+
if (this.name) {
|
|
37
|
+
// Check cache first
|
|
38
|
+
const cached = iconCache.get(this.name);
|
|
39
|
+
if (cached) {
|
|
40
|
+
if (cached instanceof Promise) {
|
|
41
|
+
this.svg = await cached;
|
|
42
|
+
} else {
|
|
43
|
+
this.svg = cached;
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Cache the promise immediately
|
|
49
|
+
const promise = (async () => {
|
|
50
|
+
try {
|
|
51
|
+
const response = await fetch(`/icons/${this.name}.svg`);
|
|
52
|
+
return response.ok ? await response.text() : this.defaultSvg;
|
|
53
|
+
} catch {
|
|
54
|
+
return this.defaultSvg;
|
|
55
|
+
}
|
|
56
|
+
})();
|
|
57
|
+
|
|
58
|
+
iconCache.set(this.name, promise);
|
|
59
|
+
|
|
60
|
+
const svgContent = await promise;
|
|
61
|
+
iconCache.set(this.name, svgContent);
|
|
62
|
+
this.svg = svgContent;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
Rendering
|
|
68
|
+
*/
|
|
69
|
+
render(){
|
|
70
|
+
return html`${unsafeHTML(this.svg)}`;
|
|
71
|
+
}
|
|
72
|
+
static styles = css`
|
|
73
|
+
:host {
|
|
74
|
+
display: inline-block;
|
|
75
|
+
height: 1.35em;
|
|
76
|
+
width: 1.35em;
|
|
77
|
+
vertical-align: top;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Animation classes */
|
|
81
|
+
:host([animation="spin"]) {
|
|
82
|
+
animation: spin 1s linear infinite;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
:host([animation="pulse"]) {
|
|
86
|
+
animation: pulse 1.5s ease-in-out infinite;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
:host([animation="bounce"]) {
|
|
90
|
+
animation: bounce 1s ease-in-out infinite;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
:host([animation="shake"]) {
|
|
94
|
+
animation: shake 0.5s ease-in-out infinite;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
:host([animation="fade"]) {
|
|
98
|
+
animation: fade 2s ease-in-out infinite;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
:host([animation="flip"]) {
|
|
102
|
+
animation: flip 2s ease-in-out infinite;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/* Keyframe definitions */
|
|
106
|
+
@keyframes spin {
|
|
107
|
+
from { transform: rotate(0deg); }
|
|
108
|
+
to { transform: rotate(360deg); }
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
@keyframes pulse {
|
|
112
|
+
0%, 100% {
|
|
113
|
+
transform: scale(1);
|
|
114
|
+
opacity: 1;
|
|
115
|
+
}
|
|
116
|
+
50% {
|
|
117
|
+
transform: scale(1.1);
|
|
118
|
+
opacity: 0.7;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@keyframes bounce {
|
|
123
|
+
0%, 20%, 50%, 80%, 100% {
|
|
124
|
+
transform: translateY(0);
|
|
125
|
+
}
|
|
126
|
+
40% {
|
|
127
|
+
transform: translateY(-0.3em);
|
|
128
|
+
}
|
|
129
|
+
60% {
|
|
130
|
+
transform: translateY(-0.15em);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
@keyframes shake {
|
|
135
|
+
0%, 100% { transform: translateX(0); }
|
|
136
|
+
10%, 30%, 50%, 70%, 90% { transform: translateX(-0.1em); }
|
|
137
|
+
20%, 40%, 60%, 80% { transform: translateX(0.1em); }
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@keyframes fade {
|
|
141
|
+
0%, 100% { opacity: 1; }
|
|
142
|
+
50% { opacity: 0.3; }
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@keyframes flip {
|
|
146
|
+
0% { transform: rotateY(0deg); }
|
|
147
|
+
50% { transform: rotateY(180deg); }
|
|
148
|
+
100% { transform: rotateY(360deg); }
|
|
149
|
+
}
|
|
150
|
+
`
|
|
151
|
+
});
|
package/gui/components/Logs.js
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
import { LitElement, html, css } from '../lit-all.min.js';
|
|
2
|
-
import './Icon.js';
|
|
3
|
-
import './Collapsible.js';
|
|
4
|
-
import { getSettings, subscribe } from './settingsStore.js';
|
|
5
|
-
|
|
6
|
-
window.customElements.define('ktf-logs', class extends LitElement {
|
|
7
|
-
/*
|
|
8
|
-
Properties
|
|
9
|
-
*/
|
|
10
|
-
static properties = {
|
|
11
|
-
level: { type: Number }
|
|
12
|
-
};
|
|
13
|
-
#logs = [];
|
|
14
|
-
#unsubscribe = null;
|
|
15
|
-
constructor(){
|
|
16
|
-
super();
|
|
17
|
-
const initial = Number(getSettings().logLevel ?? 3);
|
|
18
|
-
this.level = Number.isFinite(initial) ? initial : 3;
|
|
19
|
-
}
|
|
20
|
-
connectedCallback(){
|
|
21
|
-
super.connectedCallback();
|
|
22
|
-
this.#unsubscribe = subscribe(s => {
|
|
23
|
-
const parsed = Number(s.logLevel ?? 3);
|
|
24
|
-
this.level = Number.isFinite(parsed) ? parsed : 3;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
disconnectedCallback(){
|
|
28
|
-
super.disconnectedCallback();
|
|
29
|
-
if (this.#unsubscribe) this.#unsubscribe();
|
|
30
|
-
}
|
|
31
|
-
get logs(){
|
|
32
|
-
return this.#logs;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/*
|
|
36
|
-
Methods
|
|
37
|
-
*/
|
|
38
|
-
addLog = (...logs) => {
|
|
39
|
-
this.#logs.push(...logs);
|
|
40
|
-
this.requestUpdate();
|
|
41
|
-
};
|
|
42
|
-
clear = () => {
|
|
43
|
-
this.#logs.length = 0;
|
|
44
|
-
this.requestUpdate();
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
/*
|
|
48
|
-
Rendering
|
|
49
|
-
*/
|
|
50
|
-
render(){
|
|
51
|
-
const filtered = this.#logs.filter(l => {
|
|
52
|
-
const lvl = Number.isFinite(l?.level) ? l.level : 3;
|
|
53
|
-
return lvl <= this.level;
|
|
54
|
-
});
|
|
55
|
-
if (!filtered.length) return html``;
|
|
56
|
-
return html`
|
|
57
|
-
<link rel="stylesheet" href="/kempo.css">
|
|
58
|
-
<ktf-collapsible opened>
|
|
59
|
-
<span slot="title"><ktf-icon name="logs"></ktf-icon> Logs</span>
|
|
60
|
-
<pre class="bg-alt -mx -mt p mb0 rb">${filtered.map(l => html`<div class="${l?.type || 'log'}">${l?.message ?? ''}</div>`)}</pre>
|
|
61
|
-
</ktf-collapsible>
|
|
62
|
-
`;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
static styles = css`
|
|
66
|
-
:host { display:block; }
|
|
67
|
-
.error,.fail { color: var(--tc_danger, rgb(255, 0, 51)); }
|
|
68
|
-
.warning { color: var(--tc_warning, #b58900); }
|
|
69
|
-
.pass { color: var(--tc_success, rgb(0, 136, 0)); }
|
|
70
|
-
.progress { color: var(--tc_muted, #6b7280); }
|
|
71
|
-
.summary { color: var(--tc_primary, #3366ff); }
|
|
72
|
-
`;
|
|
73
|
-
});
|
|
1
|
+
import { LitElement, html, css } from '../lit-all.min.js';
|
|
2
|
+
import './Icon.js';
|
|
3
|
+
import './Collapsible.js';
|
|
4
|
+
import { getSettings, subscribe } from './settingsStore.js';
|
|
5
|
+
|
|
6
|
+
window.customElements.define('ktf-logs', class extends LitElement {
|
|
7
|
+
/*
|
|
8
|
+
Properties
|
|
9
|
+
*/
|
|
10
|
+
static properties = {
|
|
11
|
+
level: { type: Number }
|
|
12
|
+
};
|
|
13
|
+
#logs = [];
|
|
14
|
+
#unsubscribe = null;
|
|
15
|
+
constructor(){
|
|
16
|
+
super();
|
|
17
|
+
const initial = Number(getSettings().logLevel ?? 3);
|
|
18
|
+
this.level = Number.isFinite(initial) ? initial : 3;
|
|
19
|
+
}
|
|
20
|
+
connectedCallback(){
|
|
21
|
+
super.connectedCallback();
|
|
22
|
+
this.#unsubscribe = subscribe(s => {
|
|
23
|
+
const parsed = Number(s.logLevel ?? 3);
|
|
24
|
+
this.level = Number.isFinite(parsed) ? parsed : 3;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
disconnectedCallback(){
|
|
28
|
+
super.disconnectedCallback();
|
|
29
|
+
if (this.#unsubscribe) this.#unsubscribe();
|
|
30
|
+
}
|
|
31
|
+
get logs(){
|
|
32
|
+
return this.#logs;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/*
|
|
36
|
+
Methods
|
|
37
|
+
*/
|
|
38
|
+
addLog = (...logs) => {
|
|
39
|
+
this.#logs.push(...logs);
|
|
40
|
+
this.requestUpdate();
|
|
41
|
+
};
|
|
42
|
+
clear = () => {
|
|
43
|
+
this.#logs.length = 0;
|
|
44
|
+
this.requestUpdate();
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/*
|
|
48
|
+
Rendering
|
|
49
|
+
*/
|
|
50
|
+
render(){
|
|
51
|
+
const filtered = this.#logs.filter(l => {
|
|
52
|
+
const lvl = Number.isFinite(l?.level) ? l.level : 3;
|
|
53
|
+
return lvl <= this.level;
|
|
54
|
+
});
|
|
55
|
+
if (!filtered.length) return html``;
|
|
56
|
+
return html`
|
|
57
|
+
<link rel="stylesheet" href="/kempo.css">
|
|
58
|
+
<ktf-collapsible opened>
|
|
59
|
+
<span slot="title"><ktf-icon name="logs"></ktf-icon> Logs</span>
|
|
60
|
+
<pre class="bg-alt -mx -mt p mb0 rb">${filtered.map(l => html`<div class="${l?.type || 'log'}">${l?.message ?? ''}</div>`)}</pre>
|
|
61
|
+
</ktf-collapsible>
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static styles = css`
|
|
66
|
+
:host { display:block; }
|
|
67
|
+
.error,.fail { color: var(--tc_danger, rgb(255, 0, 51)); }
|
|
68
|
+
.warning { color: var(--tc_warning, #b58900); }
|
|
69
|
+
.pass { color: var(--tc_success, rgb(0, 136, 0)); }
|
|
70
|
+
.progress { color: var(--tc_muted, #6b7280); }
|
|
71
|
+
.summary { color: var(--tc_primary, #3366ff); }
|
|
72
|
+
`;
|
|
73
|
+
});
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import { LitElement, html } from '../lit-all.min.js';
|
|
2
|
-
import { getSettings, setSettings, subscribe } from './settingsStore.js';
|
|
3
|
-
|
|
4
|
-
window.customElements.define('ktf-setting-checkbox', class extends LitElement {
|
|
5
|
-
static properties = {
|
|
6
|
-
name: { type: String },
|
|
7
|
-
label: { type: String },
|
|
8
|
-
checked: { state: true },
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
createRenderRoot() { return this; }
|
|
12
|
-
|
|
13
|
-
connectedCallback() {
|
|
14
|
-
super.connectedCallback();
|
|
15
|
-
this.apply(getSettings());
|
|
16
|
-
this.unsub = subscribe((s) => this.apply(s));
|
|
17
|
-
}
|
|
18
|
-
disconnectedCallback() {
|
|
19
|
-
super.disconnectedCallback();
|
|
20
|
-
if (this.unsub) this.unsub();
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
apply(s) {
|
|
24
|
-
const v = this.name ? s?.[this.name] : undefined;
|
|
25
|
-
this.checked = !!v;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
onChange(e) {
|
|
29
|
-
const v = !!e.target.checked;
|
|
30
|
-
if (this.name) setSettings({ [this.name]: v });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
render() {
|
|
34
|
-
const id = `setting-${this.name || 'checkbox'}`;
|
|
35
|
-
return html`
|
|
36
|
-
<div class="d-f mb" style="align-items: center">
|
|
37
|
-
<input id="${id}" type="checkbox" style="font-size: 1.35rem" .checked=${!!this.checked} @change=${(e) => this.onChange(e)} />
|
|
38
|
-
<label for="${id}" style="line-height: 1.35rem" class="pb0">${this.label || ''}</label>
|
|
39
|
-
</div>
|
|
40
|
-
`;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
1
|
+
import { LitElement, html } from '../lit-all.min.js';
|
|
2
|
+
import { getSettings, setSettings, subscribe } from './settingsStore.js';
|
|
3
|
+
|
|
4
|
+
window.customElements.define('ktf-setting-checkbox', class extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
name: { type: String },
|
|
7
|
+
label: { type: String },
|
|
8
|
+
checked: { state: true },
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
createRenderRoot() { return this; }
|
|
12
|
+
|
|
13
|
+
connectedCallback() {
|
|
14
|
+
super.connectedCallback();
|
|
15
|
+
this.apply(getSettings());
|
|
16
|
+
this.unsub = subscribe((s) => this.apply(s));
|
|
17
|
+
}
|
|
18
|
+
disconnectedCallback() {
|
|
19
|
+
super.disconnectedCallback();
|
|
20
|
+
if (this.unsub) this.unsub();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
apply(s) {
|
|
24
|
+
const v = this.name ? s?.[this.name] : undefined;
|
|
25
|
+
this.checked = !!v;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
onChange(e) {
|
|
29
|
+
const v = !!e.target.checked;
|
|
30
|
+
if (this.name) setSettings({ [this.name]: v });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
render() {
|
|
34
|
+
const id = `setting-${this.name || 'checkbox'}`;
|
|
35
|
+
return html`
|
|
36
|
+
<div class="d-f mb" style="align-items: center">
|
|
37
|
+
<input id="${id}" type="checkbox" style="font-size: 1.35rem" .checked=${!!this.checked} @change=${(e) => this.onChange(e)} />
|
|
38
|
+
<label for="${id}" style="line-height: 1.35rem" class="pb0">${this.label || ''}</label>
|
|
39
|
+
</div>
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
});
|