@zkmake/three-meter 0.1.1 → 0.3.0
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/README.md +48 -12
- package/dist/{mount-perf-hud-Dw8KNQTt.d.ts → mount-perf-hud-B3wBLrcu.d.ts} +79 -2
- package/dist/{mount-perf-hud-CduRNym5.js → mount-perf-hud-CZNSZVYn.js} +287 -26
- package/dist/mount-perf-hud-CZNSZVYn.js.map +1 -0
- package/dist/react.d.ts +4 -3
- package/dist/react.js +18 -10
- package/dist/react.js.map +1 -1
- package/dist/styles.css +81 -10
- package/dist/ui.d.ts +3 -3
- package/dist/ui.js +2 -2
- package/package.json +1 -1
- package/dist/mount-perf-hud-CduRNym5.js.map +0 -1
|
@@ -1,3 +1,90 @@
|
|
|
1
|
+
//#region src/ui/theme.ts
|
|
2
|
+
const THEME_MODES = [
|
|
3
|
+
"dark",
|
|
4
|
+
"light",
|
|
5
|
+
"system"
|
|
6
|
+
];
|
|
7
|
+
const DARK_SCHEME_QUERY = "(prefers-color-scheme: dark)";
|
|
8
|
+
const isThemeMode = (value) => typeof value === "string" && THEME_MODES.includes(value);
|
|
9
|
+
var HudTheme = class {
|
|
10
|
+
current;
|
|
11
|
+
userPick = null;
|
|
12
|
+
listeners = /* @__PURE__ */ new Set();
|
|
13
|
+
media = null;
|
|
14
|
+
onSchemeChange = () => this.notify();
|
|
15
|
+
constructor(mode = "system") {
|
|
16
|
+
this.current = mode;
|
|
17
|
+
this.watch();
|
|
18
|
+
}
|
|
19
|
+
/** What the consumer asked for. */
|
|
20
|
+
get mode() {
|
|
21
|
+
return this.current;
|
|
22
|
+
}
|
|
23
|
+
/** What the person using the HUD picked in the panel, or `null` for no pick. */
|
|
24
|
+
get override() {
|
|
25
|
+
return this.userPick;
|
|
26
|
+
}
|
|
27
|
+
/** The layer that applies: the user's pick if there is one, else the consumer's mode. */
|
|
28
|
+
get effective() {
|
|
29
|
+
return this.userPick ?? this.current;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* `dark` or `light`, with `system` resolved against the OS preference.
|
|
33
|
+
* Where `matchMedia` is missing, `system` falls back to `dark`, the HUD's
|
|
34
|
+
* original palette.
|
|
35
|
+
*/
|
|
36
|
+
get resolved() {
|
|
37
|
+
const effective = this.effective;
|
|
38
|
+
if (effective !== "system") return effective;
|
|
39
|
+
if (!this.media) return "dark";
|
|
40
|
+
return this.media.matches ? "dark" : "light";
|
|
41
|
+
}
|
|
42
|
+
setMode(mode) {
|
|
43
|
+
if (mode === this.current) return;
|
|
44
|
+
this.current = mode;
|
|
45
|
+
this.watch();
|
|
46
|
+
this.notify();
|
|
47
|
+
}
|
|
48
|
+
setOverride(mode) {
|
|
49
|
+
if (mode === this.userPick) return;
|
|
50
|
+
this.userPick = mode;
|
|
51
|
+
this.watch();
|
|
52
|
+
this.notify();
|
|
53
|
+
}
|
|
54
|
+
/** Fires on `setMode`, `setOverride` and, in `system`, whenever the OS preference flips. */
|
|
55
|
+
subscribe(listener) {
|
|
56
|
+
this.listeners.add(listener);
|
|
57
|
+
return () => {
|
|
58
|
+
this.listeners.delete(listener);
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/** Stop tracking the OS preference and drop every subscriber. */
|
|
62
|
+
dispose() {
|
|
63
|
+
this.unwatch();
|
|
64
|
+
this.listeners.clear();
|
|
65
|
+
}
|
|
66
|
+
watch() {
|
|
67
|
+
if (this.effective !== "system") {
|
|
68
|
+
this.unwatch();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (this.media || typeof matchMedia !== "function") return;
|
|
72
|
+
this.media = matchMedia(DARK_SCHEME_QUERY);
|
|
73
|
+
this.media.addEventListener("change", this.onSchemeChange);
|
|
74
|
+
}
|
|
75
|
+
unwatch() {
|
|
76
|
+
this.media?.removeEventListener("change", this.onSchemeChange);
|
|
77
|
+
this.media = null;
|
|
78
|
+
}
|
|
79
|
+
notify() {
|
|
80
|
+
for (const listener of this.listeners) listener();
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
/** Paint the resolved theme onto an element for the stylesheet to key off. */
|
|
84
|
+
const applyTheme = (element, theme) => {
|
|
85
|
+
element.dataset.theme = theme.resolved;
|
|
86
|
+
};
|
|
87
|
+
//#endregion
|
|
1
88
|
//#region src/ui/hud-settings.ts
|
|
2
89
|
const DEFAULT_STORAGE_KEY = "three-meter";
|
|
3
90
|
const DEFAULT_DIM = false;
|
|
@@ -38,6 +125,14 @@ var HudSettings = class {
|
|
|
38
125
|
this.state.dim = enabled;
|
|
39
126
|
this.persistAndNotify();
|
|
40
127
|
}
|
|
128
|
+
/** The user's pick in the panel; `null` means none, so the consumer's option applies. */
|
|
129
|
+
get theme() {
|
|
130
|
+
return this.state.theme;
|
|
131
|
+
}
|
|
132
|
+
setTheme(mode) {
|
|
133
|
+
this.state.theme = mode;
|
|
134
|
+
this.persistAndNotify();
|
|
135
|
+
}
|
|
41
136
|
isNumberEnabled(key) {
|
|
42
137
|
return this.state.numbers.has(key);
|
|
43
138
|
}
|
|
@@ -64,7 +159,8 @@ var HudSettings = class {
|
|
|
64
159
|
const fallback = () => ({
|
|
65
160
|
dim: this.defaults.dim,
|
|
66
161
|
graphs: new Set(this.defaults.graphs),
|
|
67
|
-
numbers: new Set(this.defaults.numbers)
|
|
162
|
+
numbers: new Set(this.defaults.numbers),
|
|
163
|
+
theme: null
|
|
68
164
|
});
|
|
69
165
|
if (this.storageKey === null) return fallback();
|
|
70
166
|
try {
|
|
@@ -74,7 +170,8 @@ var HudSettings = class {
|
|
|
74
170
|
return {
|
|
75
171
|
dim: parsed.dim ?? this.defaults.dim,
|
|
76
172
|
graphs: new Set((parsed.graphs ?? this.defaults.graphs).filter(isTimingMetric)),
|
|
77
|
-
numbers: new Set(parsed.numbers ?? this.defaults.numbers)
|
|
173
|
+
numbers: new Set(parsed.numbers ?? this.defaults.numbers),
|
|
174
|
+
theme: isThemeMode(parsed.theme) ? parsed.theme : null
|
|
78
175
|
};
|
|
79
176
|
} catch {
|
|
80
177
|
return fallback();
|
|
@@ -85,7 +182,8 @@ var HudSettings = class {
|
|
|
85
182
|
localStorage.setItem(this.storageKey, JSON.stringify({
|
|
86
183
|
dim: this.state.dim,
|
|
87
184
|
graphs: [...this.state.graphs],
|
|
88
|
-
numbers: [...this.state.numbers]
|
|
185
|
+
numbers: [...this.state.numbers],
|
|
186
|
+
theme: this.state.theme ?? void 0
|
|
89
187
|
}));
|
|
90
188
|
} catch {}
|
|
91
189
|
for (const listener of this.listeners) listener();
|
|
@@ -344,7 +442,11 @@ const dockPanel = (element, options = {}) => {
|
|
|
344
442
|
//#region src/ui/icons.ts
|
|
345
443
|
const ICON_MARKUP = {
|
|
346
444
|
blend: "<circle cx=\"9\" cy=\"9\" r=\"7\"/><circle cx=\"15\" cy=\"15\" r=\"7\"/>",
|
|
445
|
+
contrast: "<circle cx=\"12\" cy=\"12\" r=\"10\"/><path d=\"M12 18a6 6 0 0 0 0-12v12z\"/>",
|
|
347
446
|
grip: "<circle cx=\"9\" cy=\"12\" r=\"1\"/><circle cx=\"9\" cy=\"5\" r=\"1\"/><circle cx=\"9\" cy=\"19\" r=\"1\"/><circle cx=\"15\" cy=\"12\" r=\"1\"/><circle cx=\"15\" cy=\"5\" r=\"1\"/><circle cx=\"15\" cy=\"19\" r=\"1\"/>",
|
|
447
|
+
monitor: "<rect width=\"20\" height=\"14\" x=\"2\" y=\"3\" rx=\"2\"/><line x1=\"8\" x2=\"16\" y1=\"21\" y2=\"21\"/><line x1=\"12\" x2=\"12\" y1=\"17\" y2=\"21\"/>",
|
|
448
|
+
moon: "<path d=\"M12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z\"/>",
|
|
449
|
+
sun: "<circle cx=\"12\" cy=\"12\" r=\"4\"/><path d=\"M12 2v2\"/><path d=\"M12 20v2\"/><path d=\"m4.93 4.93 1.41 1.41\"/><path d=\"m17.66 17.66 1.41 1.41\"/><path d=\"M2 12h2\"/><path d=\"M20 12h2\"/><path d=\"m6.34 17.66-1.41 1.41\"/><path d=\"m19.07 4.93-1.41 1.41\"/>",
|
|
348
450
|
sliders: "<line x1=\"21\" x2=\"14\" y1=\"4\" y2=\"4\"/><line x1=\"10\" x2=\"3\" y1=\"4\" y2=\"4\"/><line x1=\"21\" x2=\"12\" y1=\"12\" y2=\"12\"/><line x1=\"8\" x2=\"3\" y1=\"12\" y2=\"12\"/><line x1=\"21\" x2=\"16\" y1=\"20\" y2=\"20\"/><line x1=\"12\" x2=\"3\" y1=\"20\" y2=\"20\"/><line x1=\"14\" x2=\"14\" y1=\"2\" y2=\"6\"/><line x1=\"8\" x2=\"8\" y1=\"10\" y2=\"14\"/><line x1=\"16\" x2=\"16\" y1=\"18\" y2=\"22\"/>"
|
|
349
451
|
};
|
|
350
452
|
const createIcon = (name, className) => {
|
|
@@ -390,8 +492,14 @@ const TIMINGS = [
|
|
|
390
492
|
label: "FPS",
|
|
391
493
|
metric: "fps",
|
|
392
494
|
style: {
|
|
393
|
-
|
|
394
|
-
|
|
495
|
+
dark: {
|
|
496
|
+
fill: "rgba(74, 222, 128, 0.15)",
|
|
497
|
+
stroke: "#4ade80"
|
|
498
|
+
},
|
|
499
|
+
light: {
|
|
500
|
+
fill: "rgba(22, 163, 74, 0.12)",
|
|
501
|
+
stroke: "#16a34a"
|
|
502
|
+
}
|
|
395
503
|
},
|
|
396
504
|
unit: ""
|
|
397
505
|
},
|
|
@@ -400,8 +508,14 @@ const TIMINGS = [
|
|
|
400
508
|
label: "CPU",
|
|
401
509
|
metric: "cpu",
|
|
402
510
|
style: {
|
|
403
|
-
|
|
404
|
-
|
|
511
|
+
dark: {
|
|
512
|
+
fill: "rgba(96, 165, 250, 0.15)",
|
|
513
|
+
stroke: "#60a5fa"
|
|
514
|
+
},
|
|
515
|
+
light: {
|
|
516
|
+
fill: "rgba(37, 99, 235, 0.12)",
|
|
517
|
+
stroke: "#2563eb"
|
|
518
|
+
}
|
|
405
519
|
},
|
|
406
520
|
unit: "ms"
|
|
407
521
|
},
|
|
@@ -410,12 +524,35 @@ const TIMINGS = [
|
|
|
410
524
|
label: "GPU",
|
|
411
525
|
metric: "gpu",
|
|
412
526
|
style: {
|
|
413
|
-
|
|
414
|
-
|
|
527
|
+
dark: {
|
|
528
|
+
fill: "rgba(244, 114, 182, 0.15)",
|
|
529
|
+
stroke: "#f472b6"
|
|
530
|
+
},
|
|
531
|
+
light: {
|
|
532
|
+
fill: "rgba(219, 39, 119, 0.12)",
|
|
533
|
+
stroke: "#db2777"
|
|
534
|
+
}
|
|
415
535
|
},
|
|
416
536
|
unit: "ms"
|
|
417
537
|
}
|
|
418
538
|
];
|
|
539
|
+
const THEME_OPTIONS = [
|
|
540
|
+
{
|
|
541
|
+
icon: "sun",
|
|
542
|
+
label: "Light theme",
|
|
543
|
+
mode: "light"
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
icon: "monitor",
|
|
547
|
+
label: "Match the system theme",
|
|
548
|
+
mode: "system"
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
icon: "moon",
|
|
552
|
+
label: "Dark theme",
|
|
553
|
+
mode: "dark"
|
|
554
|
+
}
|
|
555
|
+
];
|
|
419
556
|
const formatCount = (value) => value.toLocaleString("en-US");
|
|
420
557
|
const readTiming = (sample, metric) => {
|
|
421
558
|
switch (metric) {
|
|
@@ -491,6 +628,9 @@ const NUMBERS = [
|
|
|
491
628
|
var PerformanceView = class {
|
|
492
629
|
element;
|
|
493
630
|
settings;
|
|
631
|
+
theme;
|
|
632
|
+
ownsTheme;
|
|
633
|
+
unsubscribeTheme;
|
|
494
634
|
monitor;
|
|
495
635
|
minIntervalMs;
|
|
496
636
|
mode;
|
|
@@ -500,6 +640,7 @@ var PerformanceView = class {
|
|
|
500
640
|
statValueEls = /* @__PURE__ */ new Map();
|
|
501
641
|
statCheckboxes = /* @__PURE__ */ new Map();
|
|
502
642
|
dimCheckbox;
|
|
643
|
+
themeRadios = /* @__PURE__ */ new Map();
|
|
503
644
|
hudGraphsEl;
|
|
504
645
|
hudGridEl;
|
|
505
646
|
hudGraphs = /* @__PURE__ */ new Map();
|
|
@@ -511,6 +652,9 @@ var PerformanceView = class {
|
|
|
511
652
|
constructor(options) {
|
|
512
653
|
this.monitor = options.monitor;
|
|
513
654
|
this.settings = options.settings ?? new HudSettings();
|
|
655
|
+
this.ownsTheme = !options.theme;
|
|
656
|
+
this.theme = options.theme ?? new HudTheme();
|
|
657
|
+
this.theme.setOverride(this.settings.theme);
|
|
514
658
|
this.mode = options.mode ?? "full";
|
|
515
659
|
this.minIntervalMs = 1e3 / (options.refreshHz ?? 10);
|
|
516
660
|
this.element = document.createElement("div");
|
|
@@ -519,7 +663,9 @@ var PerformanceView = class {
|
|
|
519
663
|
this.resizeObserver = new ResizeObserver(() => this.resizeCanvases());
|
|
520
664
|
this.build();
|
|
521
665
|
this.rebuildHud();
|
|
666
|
+
this.onThemeChanged();
|
|
522
667
|
this.unsubscribe = this.settings.subscribe(() => this.onSelectionChanged());
|
|
668
|
+
this.unsubscribeTheme = this.theme.subscribe(() => this.onThemeChanged());
|
|
523
669
|
}
|
|
524
670
|
start() {
|
|
525
671
|
if (this.rafId === null) this.rafId = requestAnimationFrame(this.frame);
|
|
@@ -542,6 +688,8 @@ var PerformanceView = class {
|
|
|
542
688
|
dispose() {
|
|
543
689
|
this.stop();
|
|
544
690
|
this.unsubscribe();
|
|
691
|
+
this.unsubscribeTheme();
|
|
692
|
+
if (this.ownsTheme) this.theme.dispose();
|
|
545
693
|
this.resizeObserver.disconnect();
|
|
546
694
|
this.element.remove();
|
|
547
695
|
}
|
|
@@ -562,7 +710,7 @@ var PerformanceView = class {
|
|
|
562
710
|
const valueEl = this.graphValueEls.get(config.metric);
|
|
563
711
|
valueEl.textContent = available ? this.formatTiming(config, readTiming(sample, config.metric)) : "unavailable";
|
|
564
712
|
const graph = this.graphCanvases.get(config.metric);
|
|
565
|
-
drawSparkline(graph.ctx, graph.width, graph.height, available ? this.monitor.getHistory(config.metric) : [], config.style);
|
|
713
|
+
drawSparkline(graph.ctx, graph.width, graph.height, available ? this.monitor.getHistory(config.metric) : [], config.style[this.theme.resolved]);
|
|
566
714
|
}
|
|
567
715
|
for (const config of NUMBERS) this.statValueEls.get(config.key).textContent = config.read(sample);
|
|
568
716
|
}
|
|
@@ -575,7 +723,7 @@ var PerformanceView = class {
|
|
|
575
723
|
const config = TIMINGS.find((timing) => timing.metric === metric);
|
|
576
724
|
const available = isTimingAvailable(sample, metric);
|
|
577
725
|
graph.valueEl.textContent = available ? this.formatTiming(config, readTiming(sample, metric)) : "—";
|
|
578
|
-
drawSparkline(graph.ctx, graph.width, graph.height, available ? this.monitor.getHistory(metric) : [], config.style);
|
|
726
|
+
drawSparkline(graph.ctx, graph.width, graph.height, available ? this.monitor.getHistory(metric) : [], config.style[this.theme.resolved]);
|
|
579
727
|
}
|
|
580
728
|
}
|
|
581
729
|
formatTiming(config, value) {
|
|
@@ -591,14 +739,37 @@ var PerformanceView = class {
|
|
|
591
739
|
hud.append(this.hudGraphsEl, this.hudGridEl);
|
|
592
740
|
const options = document.createElement("div");
|
|
593
741
|
options.className = "perf-monitor__section perf-monitor__options";
|
|
742
|
+
const themeRow = document.createElement("div");
|
|
743
|
+
themeRow.className = "perf-monitor__row perf-monitor__row--static";
|
|
744
|
+
const themeLabel = document.createElement("span");
|
|
745
|
+
themeLabel.className = "perf-monitor__label";
|
|
746
|
+
themeLabel.textContent = "theme";
|
|
747
|
+
const segment = document.createElement("div");
|
|
748
|
+
segment.className = "perf-monitor__segment";
|
|
749
|
+
segment.setAttribute("role", "radiogroup");
|
|
750
|
+
segment.setAttribute("aria-label", "Panel theme");
|
|
751
|
+
for (const option of THEME_OPTIONS) {
|
|
752
|
+
const radio = document.createElement("button");
|
|
753
|
+
radio.type = "button";
|
|
754
|
+
radio.className = "perf-monitor__segment-option";
|
|
755
|
+
radio.setAttribute("role", "radio");
|
|
756
|
+
radio.setAttribute("aria-checked", "false");
|
|
757
|
+
radio.setAttribute("aria-label", option.label);
|
|
758
|
+
radio.title = option.label;
|
|
759
|
+
radio.append(createIcon(option.icon, "perf-monitor__icon"));
|
|
760
|
+
radio.addEventListener("click", () => this.settings.setTheme(option.mode));
|
|
761
|
+
this.themeRadios.set(option.mode, radio);
|
|
762
|
+
segment.append(radio);
|
|
763
|
+
}
|
|
764
|
+
themeRow.append(createIcon("contrast", "perf-monitor__icon"), themeLabel, segment);
|
|
594
765
|
const dimRow = document.createElement("label");
|
|
595
766
|
dimRow.className = "perf-monitor__row";
|
|
596
767
|
this.dimCheckbox = this.buildCheckbox(this.settings.dim, "Dim the performance panel when the pointer leaves", (on) => this.settings.setDim(on));
|
|
597
768
|
const dimLabel = document.createElement("span");
|
|
598
769
|
dimLabel.className = "perf-monitor__label";
|
|
599
770
|
dimLabel.textContent = "dim on leave";
|
|
600
|
-
dimRow.append(
|
|
601
|
-
options.append(dimRow);
|
|
771
|
+
dimRow.append(createIcon("blend", "perf-monitor__icon"), dimLabel, this.dimCheckbox);
|
|
772
|
+
options.append(themeRow, dimRow);
|
|
602
773
|
const graphs = document.createElement("div");
|
|
603
774
|
graphs.className = "perf-monitor__graphs";
|
|
604
775
|
for (const config of TIMINGS) {
|
|
@@ -709,8 +880,14 @@ var PerformanceView = class {
|
|
|
709
880
|
for (const [metric, checkbox] of this.graphCheckboxes) checkbox.checked = this.settings.isGraphEnabled(metric);
|
|
710
881
|
for (const [key, checkbox] of this.statCheckboxes) checkbox.checked = this.settings.isNumberEnabled(key);
|
|
711
882
|
this.dimCheckbox.checked = this.settings.dim;
|
|
883
|
+
this.theme.setOverride(this.settings.theme);
|
|
712
884
|
this.rebuildHud();
|
|
713
885
|
}
|
|
886
|
+
/** Repaint the palette and mark the radio matching what applies (pick, else consumer mode). */
|
|
887
|
+
onThemeChanged() {
|
|
888
|
+
applyTheme(this.element, this.theme);
|
|
889
|
+
for (const [mode, radio] of this.themeRadios) radio.setAttribute("aria-checked", String(mode === this.theme.effective));
|
|
890
|
+
}
|
|
714
891
|
buildCheckbox(checked, title, onChange) {
|
|
715
892
|
const checkbox = document.createElement("input");
|
|
716
893
|
checkbox.type = "checkbox";
|
|
@@ -751,15 +928,42 @@ var PerformanceView = class {
|
|
|
751
928
|
* injects itself once per document. `.perf-monitor` is the metrics card,
|
|
752
929
|
* `.perf-hud` the floating host around it. Both namespaced so a host page can
|
|
753
930
|
* override safely; the `--perf-*` custom properties are the theming surface.
|
|
931
|
+
*
|
|
932
|
+
* Both elements carry `data-theme="dark" | "light"` (see `HudTheme`) and each
|
|
933
|
+
* resolves its own tokens from it, so the card also themes when mounted on
|
|
934
|
+
* its own, outside a `.perf-hud`.
|
|
754
935
|
*/
|
|
755
936
|
const STYLE_ATTRIBUTE = "data-three-meter";
|
|
756
937
|
const PERF_HUD_STYLES = `
|
|
938
|
+
.perf-hud,
|
|
757
939
|
.perf-monitor {
|
|
758
|
-
--perf-bg:
|
|
940
|
+
--perf-bg: rgba(22, 24, 29, 0.85);
|
|
759
941
|
--perf-fg: #e6e8eb;
|
|
942
|
+
--perf-fg-dim: #c5c8ce;
|
|
760
943
|
--perf-muted: #8b909a;
|
|
761
944
|
--perf-row: rgba(255, 255, 255, 0.04);
|
|
945
|
+
--perf-border: rgba(255, 255, 255, 0.12);
|
|
946
|
+
--perf-accent: #60a5fa;
|
|
947
|
+
--perf-shadow: 0 8px 24px rgba(0, 0, 0, 0.32);
|
|
948
|
+
|
|
949
|
+
color-scheme: dark;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
.perf-hud[data-theme="light"],
|
|
953
|
+
.perf-monitor[data-theme="light"] {
|
|
954
|
+
--perf-bg: rgba(250, 250, 252, 0.88);
|
|
955
|
+
--perf-fg: #1a1c21;
|
|
956
|
+
--perf-fg-dim: #4b5058;
|
|
957
|
+
--perf-muted: #6b7079;
|
|
958
|
+
--perf-row: rgba(0, 0, 0, 0.05);
|
|
959
|
+
--perf-border: rgba(0, 0, 0, 0.12);
|
|
960
|
+
--perf-accent: #2563eb;
|
|
961
|
+
--perf-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
|
|
762
962
|
|
|
963
|
+
color-scheme: light;
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
.perf-monitor {
|
|
763
967
|
display: flex;
|
|
764
968
|
flex-direction: column;
|
|
765
969
|
gap: 10px;
|
|
@@ -858,7 +1062,55 @@ const PERF_HUD_STYLES = `
|
|
|
858
1062
|
|
|
859
1063
|
.perf-monitor__options {
|
|
860
1064
|
padding-bottom: 8px;
|
|
861
|
-
border-bottom: 1px solid
|
|
1065
|
+
border-bottom: 1px solid var(--perf-border);
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
.perf-monitor__row--static {
|
|
1069
|
+
cursor: default;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
/* Light / system / dark, as a small segmented radio group. */
|
|
1073
|
+
.perf-monitor__segment {
|
|
1074
|
+
display: inline-flex;
|
|
1075
|
+
flex: none;
|
|
1076
|
+
gap: 1px;
|
|
1077
|
+
padding: 1px;
|
|
1078
|
+
border-radius: 4px;
|
|
1079
|
+
background: var(--perf-row);
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
.perf-monitor__segment-option {
|
|
1083
|
+
display: flex;
|
|
1084
|
+
align-items: center;
|
|
1085
|
+
justify-content: center;
|
|
1086
|
+
width: 20px;
|
|
1087
|
+
height: 16px;
|
|
1088
|
+
padding: 0;
|
|
1089
|
+
border: 0;
|
|
1090
|
+
border-radius: 3px;
|
|
1091
|
+
background: transparent;
|
|
1092
|
+
color: var(--perf-muted);
|
|
1093
|
+
cursor: pointer;
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
.perf-monitor__segment-option:hover {
|
|
1097
|
+
color: var(--perf-fg);
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.perf-monitor__segment-option[aria-checked="true"] {
|
|
1101
|
+
color: var(--perf-fg);
|
|
1102
|
+
background: var(--perf-border);
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
.perf-monitor__segment-option:focus-visible {
|
|
1106
|
+
outline: 1px solid color-mix(in srgb, var(--perf-accent) 60%, transparent);
|
|
1107
|
+
outline-offset: 1px;
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
.perf-monitor__segment-option .perf-monitor__icon {
|
|
1111
|
+
width: 11px;
|
|
1112
|
+
height: 11px;
|
|
1113
|
+
color: inherit;
|
|
862
1114
|
}
|
|
863
1115
|
|
|
864
1116
|
.perf-monitor__checkbox {
|
|
@@ -866,7 +1118,7 @@ const PERF_HUD_STYLES = `
|
|
|
866
1118
|
margin: 0;
|
|
867
1119
|
width: 12px;
|
|
868
1120
|
height: 12px;
|
|
869
|
-
accent-color:
|
|
1121
|
+
accent-color: var(--perf-accent);
|
|
870
1122
|
cursor: pointer;
|
|
871
1123
|
}
|
|
872
1124
|
|
|
@@ -964,9 +1216,9 @@ const PERF_HUD_STYLES = `
|
|
|
964
1216
|
z-index: 1;
|
|
965
1217
|
max-height: 70vh;
|
|
966
1218
|
overflow: auto;
|
|
967
|
-
background:
|
|
1219
|
+
background: var(--perf-bg);
|
|
968
1220
|
border-radius: 6px;
|
|
969
|
-
box-shadow:
|
|
1221
|
+
box-shadow: var(--perf-shadow);
|
|
970
1222
|
backdrop-filter: blur(2px);
|
|
971
1223
|
pointer-events: auto;
|
|
972
1224
|
transition: opacity 0.25s ease;
|
|
@@ -1027,9 +1279,9 @@ const PERF_HUD_STYLES = `
|
|
|
1027
1279
|
padding: 0;
|
|
1028
1280
|
border: 0;
|
|
1029
1281
|
border-radius: 999px;
|
|
1030
|
-
background:
|
|
1031
|
-
box-shadow:
|
|
1032
|
-
color:
|
|
1282
|
+
background: var(--perf-bg);
|
|
1283
|
+
box-shadow: var(--perf-shadow);
|
|
1284
|
+
color: var(--perf-fg-dim);
|
|
1033
1285
|
cursor: pointer;
|
|
1034
1286
|
backdrop-filter: blur(2px);
|
|
1035
1287
|
}
|
|
@@ -1050,8 +1302,8 @@ const PERF_HUD_STYLES = `
|
|
|
1050
1302
|
.perf-hud__disc:hover,
|
|
1051
1303
|
.perf-hud__disc:focus-visible,
|
|
1052
1304
|
.perf-hud__disc[aria-pressed="true"] {
|
|
1053
|
-
color:
|
|
1054
|
-
outline: 1px solid
|
|
1305
|
+
color: var(--perf-fg);
|
|
1306
|
+
outline: 1px solid color-mix(in srgb, var(--perf-accent) 60%, transparent);
|
|
1055
1307
|
outline-offset: 1px;
|
|
1056
1308
|
}
|
|
1057
1309
|
`;
|
|
@@ -1080,6 +1332,7 @@ const disc = (label, className, icon) => {
|
|
|
1080
1332
|
const mountPerfHud = (monitor, options = {}) => {
|
|
1081
1333
|
const storageKey = options.storageKey === void 0 ? DEFAULT_STORAGE_KEY : options.storageKey;
|
|
1082
1334
|
const settings = options.settings ?? new HudSettings({ storageKey });
|
|
1335
|
+
const theme = new HudTheme(options.theme ?? "system");
|
|
1083
1336
|
const parent = options.parent ?? document.body;
|
|
1084
1337
|
if (options.injectStyles ?? true) injectStyles(parent.ownerDocument);
|
|
1085
1338
|
const host = document.createElement("div");
|
|
@@ -1098,7 +1351,8 @@ const mountPerfHud = (monitor, options = {}) => {
|
|
|
1098
1351
|
mode: options.mode ?? "compact",
|
|
1099
1352
|
monitor,
|
|
1100
1353
|
refreshHz: options.refreshHz,
|
|
1101
|
-
settings
|
|
1354
|
+
settings,
|
|
1355
|
+
theme
|
|
1102
1356
|
});
|
|
1103
1357
|
host.append(hotspot, tools, view.element);
|
|
1104
1358
|
parent.append(host);
|
|
@@ -1110,7 +1364,9 @@ const mountPerfHud = (monitor, options = {}) => {
|
|
|
1110
1364
|
};
|
|
1111
1365
|
applyMode();
|
|
1112
1366
|
applyDim();
|
|
1367
|
+
applyTheme(host, theme);
|
|
1113
1368
|
const unsubscribe = settings.subscribe(applyDim);
|
|
1369
|
+
const unsubscribeTheme = theme.subscribe(() => applyTheme(host, theme));
|
|
1114
1370
|
const dock = dockPanel(host, {
|
|
1115
1371
|
defaultPlacement: options.defaultPlacement,
|
|
1116
1372
|
handle: grip,
|
|
@@ -1159,18 +1415,23 @@ const mountPerfHud = (monitor, options = {}) => {
|
|
|
1159
1415
|
host.removeEventListener("pointerleave", onLeave);
|
|
1160
1416
|
host.removeEventListener("pointerdown", onDown);
|
|
1161
1417
|
unsubscribe();
|
|
1418
|
+
unsubscribeTheme();
|
|
1162
1419
|
dock.dispose();
|
|
1163
1420
|
view.dispose();
|
|
1421
|
+
theme.dispose();
|
|
1164
1422
|
host.remove();
|
|
1165
1423
|
},
|
|
1166
1424
|
element: host,
|
|
1167
1425
|
getMode: () => view.getMode(),
|
|
1168
1426
|
setMode,
|
|
1427
|
+
getTheme: () => theme.mode,
|
|
1428
|
+
setTheme: (mode) => theme.setMode(mode),
|
|
1169
1429
|
settings,
|
|
1430
|
+
theme,
|
|
1170
1431
|
view
|
|
1171
1432
|
};
|
|
1172
1433
|
};
|
|
1173
1434
|
//#endregion
|
|
1174
|
-
export { dockPanel as a, PerformanceView as i, PERF_HUD_STYLES as n, DEFAULT_STORAGE_KEY as o, injectStyles as r, HudSettings as s, mountPerfHud as t };
|
|
1435
|
+
export { dockPanel as a, HudTheme as c, PerformanceView as i, THEME_MODES as l, PERF_HUD_STYLES as n, DEFAULT_STORAGE_KEY as o, injectStyles as r, HudSettings as s, mountPerfHud as t, isThemeMode as u };
|
|
1175
1436
|
|
|
1176
|
-
//# sourceMappingURL=mount-perf-hud-
|
|
1437
|
+
//# sourceMappingURL=mount-perf-hud-CZNSZVYn.js.map
|