nuxt-devtools-observatory 0.1.26 → 0.1.30
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 +50 -11
- package/client/dist/assets/index-BCaKoHBH.js +17 -0
- package/client/dist/assets/index-BmGW_M3W.css +1 -0
- package/client/dist/index.html +2 -2
- package/client/src/App.vue +2 -6
- package/client/src/composables/useResizablePane.ts +65 -0
- package/client/src/stores/observatory.ts +162 -218
- package/client/src/style.css +203 -28
- package/client/src/views/ComposableTracker.vue +327 -294
- package/client/src/views/FetchDashboard.vue +104 -132
- package/client/src/views/ProvideInjectGraph.vue +101 -118
- package/client/src/views/RenderHeatmap.vue +192 -157
- package/client/src/views/TransitionTimeline.vue +166 -130
- package/client/tsconfig.json +3 -1
- package/client/vite.config.ts +12 -1
- package/dist/module.d.mts +6 -1
- package/dist/module.json +1 -1
- package/dist/module.mjs +238 -186
- package/dist/runtime/composables/fetch-registry.js +3 -0
- package/dist/runtime/plugin.js +89 -66
- package/package.json +12 -3
- package/client/dist/assets/index-1-H6UMCK.css +0 -1
- package/client/dist/assets/index-eSUuhYQ0.js +0 -17
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed, defineComponent, h, ref, watch, type VNode } from 'vue'
|
|
3
|
-
import {
|
|
3
|
+
import { useResizablePane } from '@observatory-client/composables/useResizablePane'
|
|
4
|
+
import { useObservatoryData, openInEditor as openInEditorFromStore } from '@observatory-client/stores/observatory'
|
|
5
|
+
import type { RenderEntry, RenderEvent } from '@observatory/types/snapshot'
|
|
4
6
|
|
|
5
7
|
interface ComponentNode {
|
|
6
8
|
id: string
|
|
@@ -170,6 +172,7 @@ const TreeNode = defineComponent({
|
|
|
170
172
|
})
|
|
171
173
|
|
|
172
174
|
const { renders, connected } = useObservatoryData()
|
|
175
|
+
const { paneWidth: detailWidth, onHandleMouseDown: onDetailHandleMouseDown } = useResizablePane(280, 'observatory:heatmap:detailWidth')
|
|
173
176
|
|
|
174
177
|
const activeMode = ref<'count' | 'time'>('count')
|
|
175
178
|
// Route filter — '' means show all routes
|
|
@@ -687,17 +690,7 @@ function basename(file: string) {
|
|
|
687
690
|
}
|
|
688
691
|
|
|
689
692
|
function openInEditor(file: string) {
|
|
690
|
-
|
|
691
|
-
return
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
const origin = getObservatoryOrigin()
|
|
695
|
-
|
|
696
|
-
if (!origin) {
|
|
697
|
-
return
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
window.top?.postMessage({ type: 'observatory:open-in-editor', file }, origin)
|
|
693
|
+
openInEditorFromStore(file)
|
|
701
694
|
}
|
|
702
695
|
|
|
703
696
|
function pathLabel(node: ComponentNode) {
|
|
@@ -715,13 +708,13 @@ function formatTimestamp(t: number): string {
|
|
|
715
708
|
</script>
|
|
716
709
|
|
|
717
710
|
<template>
|
|
718
|
-
<div class="view">
|
|
719
|
-
<div class="
|
|
720
|
-
<div class="
|
|
711
|
+
<div class="render-heatmap tracker-view">
|
|
712
|
+
<div class="render-heatmap__controls tracker-toolbar">
|
|
713
|
+
<div class="render-heatmap__mode-group">
|
|
721
714
|
<button :class="{ active: activeMode === 'count' }" @click="activeMode = 'count'">render count</button>
|
|
722
715
|
<button :class="{ active: activeMode === 'time' }" @click="activeMode = 'time'">render time</button>
|
|
723
716
|
</div>
|
|
724
|
-
<div class="
|
|
717
|
+
<div class="render-heatmap__threshold-group">
|
|
725
718
|
<span class="muted text-sm">threshold</span>
|
|
726
719
|
<input
|
|
727
720
|
v-model.number="activeThreshold"
|
|
@@ -729,7 +722,7 @@ function formatTimestamp(t: number): string {
|
|
|
729
722
|
:min="activeMode === 'count' ? 2 : 4"
|
|
730
723
|
:max="activeMode === 'count' ? 20 : 100"
|
|
731
724
|
:step="activeMode === 'count' ? 1 : 4"
|
|
732
|
-
|
|
725
|
+
class="render-heatmap__threshold-range"
|
|
733
726
|
/>
|
|
734
727
|
<span class="mono text-sm">{{ activeThreshold }}{{ activeMode === 'count' ? '+ renders' : 'ms+' }}</span>
|
|
735
728
|
</div>
|
|
@@ -738,12 +731,12 @@ function formatTimestamp(t: number): string {
|
|
|
738
731
|
<option value="">all routes</option>
|
|
739
732
|
<option v-for="r in knownRoutes" :key="r" :value="r">{{ r }}</option>
|
|
740
733
|
</select>
|
|
741
|
-
<button :class="{ active: frozen }"
|
|
734
|
+
<button :class="{ active: frozen }" class="render-heatmap__freeze tracker-toolbar__spacer" @click="toggleFreeze">
|
|
742
735
|
{{ frozen ? 'unfreeze' : 'freeze snapshot' }}
|
|
743
736
|
</button>
|
|
744
737
|
</div>
|
|
745
738
|
|
|
746
|
-
<div class="stats-row">
|
|
739
|
+
<div class="render-heatmap__stats tracker-stats-row">
|
|
747
740
|
<div class="stat-card">
|
|
748
741
|
<div class="stat-label">components</div>
|
|
749
742
|
<div class="stat-val">{{ allComponents.length }}</div>
|
|
@@ -754,7 +747,7 @@ function formatTimestamp(t: number): string {
|
|
|
754
747
|
</div>
|
|
755
748
|
<div class="stat-card">
|
|
756
749
|
<div class="stat-label">hot</div>
|
|
757
|
-
<div class="stat-val
|
|
750
|
+
<div class="stat-val stat-val--error">{{ hotCount }}</div>
|
|
758
751
|
</div>
|
|
759
752
|
<div class="stat-card">
|
|
760
753
|
<div class="stat-label">avg time</div>
|
|
@@ -762,32 +755,37 @@ function formatTimestamp(t: number): string {
|
|
|
762
755
|
</div>
|
|
763
756
|
</div>
|
|
764
757
|
|
|
765
|
-
<div class="
|
|
766
|
-
<aside class="
|
|
767
|
-
<div class="
|
|
758
|
+
<div class="render-heatmap__inspector">
|
|
759
|
+
<aside class="render-heatmap__roots-panel">
|
|
760
|
+
<div class="render-heatmap__panel-title tracker-section-label">apps</div>
|
|
768
761
|
<button
|
|
769
762
|
v-for="entry in appEntries"
|
|
770
763
|
:key="entry.id"
|
|
771
|
-
class="
|
|
764
|
+
class="render-heatmap__root-item"
|
|
772
765
|
:class="{ active: activeRootId === entry.id }"
|
|
773
766
|
@click="selectRoot(entry.root)"
|
|
774
767
|
>
|
|
775
|
-
<div class="
|
|
776
|
-
<span class="
|
|
777
|
-
<span class="
|
|
768
|
+
<div class="render-heatmap__root-copy">
|
|
769
|
+
<span class="render-heatmap__root-label mono">{{ entry.label }}</span>
|
|
770
|
+
<span class="render-heatmap__root-sub muted mono">{{ entry.root.label }}</span>
|
|
778
771
|
</div>
|
|
779
|
-
<span class="
|
|
772
|
+
<span class="render-heatmap__root-meta mono">{{ entry.meta }}</span>
|
|
780
773
|
</button>
|
|
781
|
-
<div v-if="!appEntries.length" class="
|
|
774
|
+
<div v-if="!appEntries.length" class="render-heatmap__detail-empty">no apps match</div>
|
|
782
775
|
</aside>
|
|
783
776
|
|
|
784
|
-
<section class="
|
|
785
|
-
<div class="
|
|
786
|
-
<input
|
|
777
|
+
<section class="render-heatmap__tree-panel">
|
|
778
|
+
<div class="render-heatmap__tree-toolbar">
|
|
779
|
+
<input
|
|
780
|
+
:value="search"
|
|
781
|
+
class="render-heatmap__search-input mono"
|
|
782
|
+
placeholder="Find components..."
|
|
783
|
+
@input="updateSearch"
|
|
784
|
+
/>
|
|
787
785
|
</div>
|
|
788
786
|
|
|
789
|
-
<div class="
|
|
790
|
-
<div class="tree-canvas">
|
|
787
|
+
<div class="render-heatmap__tree-frame">
|
|
788
|
+
<div class="render-heatmap__tree-canvas tree-canvas">
|
|
791
789
|
<TreeNode
|
|
792
790
|
v-for="root in visibleTreeRoots"
|
|
793
791
|
:key="root.id"
|
|
@@ -800,47 +798,62 @@ function formatTimestamp(t: number): string {
|
|
|
800
798
|
@toggle="toggleNode"
|
|
801
799
|
/>
|
|
802
800
|
</div>
|
|
803
|
-
<div v-if="!visibleTreeRoots.length" class="
|
|
801
|
+
<div v-if="!visibleTreeRoots.length" class="render-heatmap__detail-empty">
|
|
804
802
|
{{ connected ? 'No render activity recorded yet.' : 'Waiting for connection to the Nuxt app…' }}
|
|
805
803
|
</div>
|
|
806
804
|
</div>
|
|
807
805
|
</section>
|
|
808
806
|
|
|
809
|
-
<
|
|
807
|
+
<div class="tracker-resize-handle" @mousedown="onDetailHandleMouseDown" />
|
|
808
|
+
|
|
809
|
+
<aside class="render-heatmap__detail-panel tracker-detail-panel" :style="{ width: detailWidth + 'px' }">
|
|
810
810
|
<template v-if="activeSelected">
|
|
811
|
-
<div class="
|
|
812
|
-
<span class="mono bold"
|
|
811
|
+
<div class="render-heatmap__detail-header">
|
|
812
|
+
<span class="render-heatmap__detail-title mono bold">{{ activeSelected.label }}</span>
|
|
813
813
|
<button @click="activeSelectedId = null">×</button>
|
|
814
814
|
</div>
|
|
815
815
|
|
|
816
|
-
<div class="
|
|
817
|
-
<span class="
|
|
816
|
+
<div class="render-heatmap__detail-pill-row">
|
|
817
|
+
<span class="render-heatmap__detail-pill mono">
|
|
818
818
|
{{ activeSelected.rerenders + activeSelected.mountCount }} render{{
|
|
819
819
|
activeSelected.rerenders + activeSelected.mountCount !== 1 ? 's' : ''
|
|
820
820
|
}}
|
|
821
821
|
</span>
|
|
822
|
-
<span class="
|
|
822
|
+
<span class="render-heatmap__detail-pill render-heatmap__detail-pill--muted mono muted">
|
|
823
823
|
{{ activeSelected.mountCount }} mount{{ activeSelected.mountCount !== 1 ? 's' : '' }}
|
|
824
824
|
</span>
|
|
825
|
-
<span v-if="activeSelected.rerenders" class="
|
|
825
|
+
<span v-if="activeSelected.rerenders" class="render-heatmap__detail-pill mono">
|
|
826
826
|
{{ activeSelected.rerenders }} re-render{{ activeSelected.rerenders !== 1 ? 's' : '' }}
|
|
827
827
|
</span>
|
|
828
|
-
<span
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
828
|
+
<span
|
|
829
|
+
v-if="activeSelected.isPersistent"
|
|
830
|
+
class="render-heatmap__detail-pill render-heatmap__detail-pill--persistent mono"
|
|
831
|
+
>
|
|
832
|
+
persistent
|
|
833
|
+
</span>
|
|
834
|
+
<span
|
|
835
|
+
v-if="activeSelected.isHydrationMount"
|
|
836
|
+
class="render-heatmap__detail-pill render-heatmap__detail-pill--hydrated mono"
|
|
837
|
+
>
|
|
838
|
+
hydrated
|
|
839
|
+
</span>
|
|
840
|
+
<span class="render-heatmap__detail-pill mono">{{ activeSelected.avgMs.toFixed(1) }}ms avg</span>
|
|
841
|
+
<span
|
|
842
|
+
class="render-heatmap__detail-pill mono"
|
|
843
|
+
:class="{ 'render-heatmap__detail-pill--hot': isHot(activeSelected) }"
|
|
844
|
+
>
|
|
832
845
|
{{ isHot(activeSelected) ? 'hot' : 'cool' }}
|
|
833
846
|
</span>
|
|
834
847
|
</div>
|
|
835
848
|
|
|
836
|
-
<div class="section-label">identity</div>
|
|
837
|
-
<div class="
|
|
849
|
+
<div class="tracker-section-label render-heatmap__section-label">identity</div>
|
|
850
|
+
<div class="render-heatmap__meta-grid">
|
|
838
851
|
<span class="muted text-sm">label</span>
|
|
839
852
|
<span class="mono text-sm">{{ activeSelected.label }}</span>
|
|
840
853
|
<span class="muted text-sm">path</span>
|
|
841
854
|
<span class="mono text-sm">{{ pathLabel(activeSelected) }}</span>
|
|
842
855
|
<span class="muted text-sm">file</span>
|
|
843
|
-
<span class="mono text-sm muted"
|
|
856
|
+
<span class="render-heatmap__file-row mono text-sm muted">
|
|
844
857
|
{{ activeSelected.file }}
|
|
845
858
|
<button
|
|
846
859
|
v-if="activeSelected.file && activeSelected.file !== 'unknown'"
|
|
@@ -859,8 +872,8 @@ function formatTimestamp(t: number): string {
|
|
|
859
872
|
<span class="mono text-sm">{{ activeSelected.children.length }}</span>
|
|
860
873
|
</div>
|
|
861
874
|
|
|
862
|
-
<div class="section-label">rendering</div>
|
|
863
|
-
<div class="
|
|
875
|
+
<div class="tracker-section-label render-heatmap__section-label">rendering</div>
|
|
876
|
+
<div class="render-heatmap__meta-grid">
|
|
864
877
|
<span class="muted text-sm">total renders</span>
|
|
865
878
|
<span class="mono text-sm">{{ activeSelected.rerenders + activeSelected.mountCount }}</span>
|
|
866
879
|
<span class="muted text-sm">re-renders</span>
|
|
@@ -868,7 +881,7 @@ function formatTimestamp(t: number): string {
|
|
|
868
881
|
<span class="muted text-sm">mounts</span>
|
|
869
882
|
<span class="mono text-sm">{{ activeSelected.mountCount }}</span>
|
|
870
883
|
<span class="muted text-sm">persistent</span>
|
|
871
|
-
<span class="mono text-sm" :
|
|
884
|
+
<span class="mono text-sm" :class="{ 'render-heatmap__persistent-value': activeSelected.isPersistent }">
|
|
872
885
|
{{ activeSelected.isPersistent ? 'yes — survives navigation' : 'no' }}
|
|
873
886
|
</span>
|
|
874
887
|
<span class="muted text-sm">hydration mount</span>
|
|
@@ -881,47 +894,42 @@ function formatTimestamp(t: number): string {
|
|
|
881
894
|
<span class="mono text-sm">{{ activeMode === 'count' ? 're-render count' : 'render time' }}</span>
|
|
882
895
|
</div>
|
|
883
896
|
|
|
884
|
-
<div class="section-label">triggers</div>
|
|
885
|
-
<div v-for="trigger in activeSelected.triggers" :key="trigger" class="
|
|
897
|
+
<div class="tracker-section-label render-heatmap__section-label">triggers</div>
|
|
898
|
+
<div v-for="trigger in activeSelected.triggers" :key="trigger" class="render-heatmap__trigger-item mono text-sm">
|
|
899
|
+
{{ trigger }}
|
|
900
|
+
</div>
|
|
886
901
|
<div v-if="!activeSelected.triggers.length" class="muted text-sm">no triggers recorded</div>
|
|
887
902
|
|
|
888
|
-
<div class="section-label
|
|
903
|
+
<div class="tracker-section-label render-heatmap__section-label render-heatmap__section-label--timeline">
|
|
889
904
|
render timeline
|
|
890
|
-
<span class="
|
|
891
|
-
({{ activeSelected.timeline.length }})
|
|
892
|
-
</span>
|
|
905
|
+
<span class="render-heatmap__section-label-meta muted">({{ activeSelected.timeline.length }})</span>
|
|
893
906
|
</div>
|
|
894
907
|
<div v-if="!activeSelected.timeline.length" class="muted text-sm">no timeline events yet</div>
|
|
895
|
-
<div v-else class="
|
|
896
|
-
<div
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
<span class="
|
|
908
|
+
<div v-else class="render-heatmap__timeline-list">
|
|
909
|
+
<div
|
|
910
|
+
v-for="(event, idx) in [...activeSelected.timeline].reverse().slice(0, 30)"
|
|
911
|
+
:key="idx"
|
|
912
|
+
class="render-heatmap__timeline-row"
|
|
913
|
+
>
|
|
914
|
+
<span class="render-heatmap__timeline-kind mono" :class="event.kind">{{ event.kind }}</span>
|
|
915
|
+
<span class="render-heatmap__timeline-time mono muted">{{ formatTimestamp(event.t) }}</span>
|
|
916
|
+
<span class="render-heatmap__timeline-dur mono">{{ formatMs(event.durationMs) }}</span>
|
|
917
|
+
<span v-if="event.triggerKey" class="render-heatmap__timeline-trigger mono muted">{{ event.triggerKey }}</span>
|
|
918
|
+
<span class="render-heatmap__timeline-route mono muted">{{ event.route }}</span>
|
|
902
919
|
</div>
|
|
903
|
-
<div v-if="activeSelected.timeline.length > 30" class="muted text-sm"
|
|
920
|
+
<div v-if="activeSelected.timeline.length > 30" class="render-heatmap__compact-muted muted text-sm">
|
|
904
921
|
… {{ activeSelected.timeline.length - 30 }} earlier events
|
|
905
922
|
</div>
|
|
906
923
|
</div>
|
|
907
924
|
</template>
|
|
908
|
-
<div v-else class="
|
|
925
|
+
<div v-else class="render-heatmap__detail-empty">click a component to inspect</div>
|
|
909
926
|
</aside>
|
|
910
927
|
</div>
|
|
911
928
|
</div>
|
|
912
929
|
</template>
|
|
913
930
|
|
|
914
931
|
<style scoped>
|
|
915
|
-
.
|
|
916
|
-
display: flex;
|
|
917
|
-
flex-direction: column;
|
|
918
|
-
height: 100%;
|
|
919
|
-
overflow: hidden;
|
|
920
|
-
padding: 12px;
|
|
921
|
-
gap: 10px;
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
.controls {
|
|
932
|
+
.render-heatmap__controls {
|
|
925
933
|
display: flex;
|
|
926
934
|
align-items: center;
|
|
927
935
|
gap: 8px;
|
|
@@ -929,65 +937,67 @@ function formatTimestamp(t: number): string {
|
|
|
929
937
|
flex-wrap: wrap;
|
|
930
938
|
}
|
|
931
939
|
|
|
932
|
-
.
|
|
940
|
+
.render-heatmap__mode-group {
|
|
933
941
|
display: flex;
|
|
934
942
|
gap: 2px;
|
|
935
943
|
}
|
|
936
944
|
|
|
937
|
-
.
|
|
945
|
+
.render-heatmap__threshold-group {
|
|
938
946
|
display: flex;
|
|
939
947
|
align-items: center;
|
|
940
948
|
gap: 6px;
|
|
941
949
|
}
|
|
942
950
|
|
|
943
|
-
.
|
|
944
|
-
|
|
945
|
-
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
946
|
-
gap: 8px;
|
|
947
|
-
flex-shrink: 0;
|
|
951
|
+
.render-heatmap__threshold-range {
|
|
952
|
+
width: 90px;
|
|
948
953
|
}
|
|
949
954
|
|
|
950
955
|
.stat-sub {
|
|
951
|
-
margin-top:
|
|
952
|
-
font-size:
|
|
956
|
+
margin-top: var(--tracker-space-1);
|
|
957
|
+
font-size: var(--tracker-font-size-sm);
|
|
953
958
|
color: var(--text3);
|
|
954
959
|
}
|
|
955
960
|
|
|
956
|
-
.
|
|
957
|
-
display:
|
|
958
|
-
|
|
959
|
-
gap: 12px;
|
|
961
|
+
.render-heatmap__inspector {
|
|
962
|
+
display: flex;
|
|
963
|
+
gap: 0;
|
|
960
964
|
flex: 1;
|
|
961
965
|
min-height: 0;
|
|
962
966
|
}
|
|
963
967
|
|
|
964
|
-
.
|
|
965
|
-
.
|
|
966
|
-
|
|
967
|
-
|
|
968
|
+
.render-heatmap__roots-panel,
|
|
969
|
+
.render-heatmap__detail-panel {
|
|
970
|
+
flex-shrink: 0;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
.render-heatmap__roots-panel {
|
|
974
|
+
width: 240px;
|
|
975
|
+
margin-right: 12px;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
.render-heatmap__roots-panel,
|
|
979
|
+
.render-heatmap__tree-panel,
|
|
980
|
+
.render-heatmap__detail-panel {
|
|
981
|
+
border: var(--tracker-border-width) solid var(--border);
|
|
968
982
|
border-radius: var(--radius-lg);
|
|
969
983
|
background: var(--bg3);
|
|
970
984
|
min-height: 0;
|
|
971
985
|
}
|
|
972
986
|
|
|
973
|
-
.
|
|
974
|
-
.
|
|
987
|
+
.render-heatmap__roots-panel,
|
|
988
|
+
.render-heatmap__detail-panel {
|
|
975
989
|
display: flex;
|
|
976
990
|
flex-direction: column;
|
|
977
991
|
overflow: auto;
|
|
978
|
-
padding:
|
|
979
|
-
gap:
|
|
992
|
+
padding: var(--tracker-space-3);
|
|
993
|
+
gap: var(--tracker-space-2);
|
|
980
994
|
}
|
|
981
995
|
|
|
982
|
-
.
|
|
983
|
-
|
|
984
|
-
font-weight: 500;
|
|
985
|
-
text-transform: uppercase;
|
|
986
|
-
letter-spacing: 0.4px;
|
|
987
|
-
color: var(--text3);
|
|
996
|
+
.render-heatmap__panel-title {
|
|
997
|
+
margin: 0;
|
|
988
998
|
}
|
|
989
999
|
|
|
990
|
-
.
|
|
1000
|
+
.render-heatmap__root-item {
|
|
991
1001
|
display: flex;
|
|
992
1002
|
align-items: center;
|
|
993
1003
|
justify-content: space-between;
|
|
@@ -1001,44 +1011,46 @@ function formatTimestamp(t: number): string {
|
|
|
1001
1011
|
text-align: left;
|
|
1002
1012
|
}
|
|
1003
1013
|
|
|
1004
|
-
.
|
|
1014
|
+
.render-heatmap__root-item.active {
|
|
1005
1015
|
border-color: var(--teal);
|
|
1006
1016
|
background: color-mix(in srgb, var(--teal) 16%, var(--bg2));
|
|
1007
1017
|
}
|
|
1008
1018
|
|
|
1009
|
-
.
|
|
1019
|
+
.render-heatmap__root-label {
|
|
1010
1020
|
overflow: hidden;
|
|
1011
1021
|
text-overflow: ellipsis;
|
|
1012
1022
|
white-space: nowrap;
|
|
1013
1023
|
}
|
|
1014
1024
|
|
|
1015
|
-
.
|
|
1025
|
+
.render-heatmap__root-copy {
|
|
1016
1026
|
display: flex;
|
|
1017
1027
|
flex-direction: column;
|
|
1018
1028
|
min-width: 0;
|
|
1019
1029
|
}
|
|
1020
1030
|
|
|
1021
|
-
.
|
|
1022
|
-
font-size:
|
|
1031
|
+
.render-heatmap__root-sub {
|
|
1032
|
+
font-size: var(--tracker-font-size-sm);
|
|
1023
1033
|
}
|
|
1024
1034
|
|
|
1025
|
-
.
|
|
1035
|
+
.render-heatmap__root-meta {
|
|
1026
1036
|
color: var(--text3);
|
|
1027
|
-
font-size:
|
|
1037
|
+
font-size: var(--tracker-font-size-sm);
|
|
1028
1038
|
}
|
|
1029
1039
|
|
|
1030
|
-
.
|
|
1040
|
+
.render-heatmap__tree-panel {
|
|
1031
1041
|
display: flex;
|
|
1032
1042
|
flex-direction: column;
|
|
1033
1043
|
overflow: hidden;
|
|
1044
|
+
flex: 1;
|
|
1045
|
+
min-width: 0;
|
|
1034
1046
|
}
|
|
1035
1047
|
|
|
1036
|
-
.
|
|
1037
|
-
padding:
|
|
1038
|
-
border-bottom:
|
|
1048
|
+
.render-heatmap__tree-toolbar {
|
|
1049
|
+
padding: var(--tracker-space-3);
|
|
1050
|
+
border-bottom: var(--tracker-border-width) solid var(--border);
|
|
1039
1051
|
}
|
|
1040
1052
|
|
|
1041
|
-
.
|
|
1053
|
+
.render-heatmap__search-input {
|
|
1042
1054
|
width: 100%;
|
|
1043
1055
|
padding: 10px 12px;
|
|
1044
1056
|
border: 1px solid var(--border);
|
|
@@ -1047,14 +1059,14 @@ function formatTimestamp(t: number): string {
|
|
|
1047
1059
|
color: var(--text);
|
|
1048
1060
|
}
|
|
1049
1061
|
|
|
1050
|
-
.
|
|
1062
|
+
.render-heatmap__tree-frame {
|
|
1051
1063
|
flex: 1;
|
|
1052
1064
|
min-height: 0;
|
|
1053
1065
|
overflow: auto;
|
|
1054
|
-
padding:
|
|
1066
|
+
padding: var(--tracker-space-3);
|
|
1055
1067
|
}
|
|
1056
1068
|
|
|
1057
|
-
|
|
1069
|
+
.render-heatmap__tree-canvas {
|
|
1058
1070
|
display: inline-block;
|
|
1059
1071
|
min-width: 100%;
|
|
1060
1072
|
width: max-content;
|
|
@@ -1206,72 +1218,77 @@ function formatTimestamp(t: number): string {
|
|
|
1206
1218
|
border-left: 1px solid color-mix(in srgb, var(--border) 72%, transparent);
|
|
1207
1219
|
}
|
|
1208
1220
|
|
|
1209
|
-
.
|
|
1221
|
+
.render-heatmap__detail-empty {
|
|
1210
1222
|
display: flex;
|
|
1211
1223
|
align-items: center;
|
|
1212
1224
|
justify-content: center;
|
|
1213
1225
|
height: 100%;
|
|
1214
1226
|
color: var(--text3);
|
|
1215
|
-
font-size:
|
|
1227
|
+
font-size: var(--tracker-font-size-md);
|
|
1216
1228
|
}
|
|
1217
1229
|
|
|
1218
|
-
.
|
|
1230
|
+
.render-heatmap__detail-header {
|
|
1219
1231
|
display: flex;
|
|
1220
1232
|
align-items: center;
|
|
1221
1233
|
justify-content: space-between;
|
|
1222
1234
|
}
|
|
1223
1235
|
|
|
1224
|
-
.
|
|
1236
|
+
.render-heatmap__detail-title {
|
|
1237
|
+
font-size: var(--tracker-font-size-md);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
.render-heatmap__meta-grid {
|
|
1225
1241
|
display: grid;
|
|
1226
1242
|
grid-template-columns: auto 1fr;
|
|
1227
|
-
gap:
|
|
1243
|
+
gap: var(--tracker-space-1) var(--tracker-space-3);
|
|
1228
1244
|
}
|
|
1229
1245
|
|
|
1230
|
-
.
|
|
1246
|
+
.render-heatmap__detail-pill-row {
|
|
1231
1247
|
display: flex;
|
|
1232
1248
|
flex-wrap: wrap;
|
|
1233
1249
|
gap: 6px;
|
|
1234
1250
|
}
|
|
1235
1251
|
|
|
1236
|
-
.
|
|
1252
|
+
.render-heatmap__detail-pill {
|
|
1237
1253
|
border: 1px solid var(--border);
|
|
1238
1254
|
border-radius: 999px;
|
|
1239
1255
|
padding: 4px 8px;
|
|
1240
1256
|
background: var(--bg2);
|
|
1241
|
-
font-size:
|
|
1257
|
+
font-size: var(--tracker-font-size-sm);
|
|
1242
1258
|
}
|
|
1243
1259
|
|
|
1244
|
-
.
|
|
1260
|
+
.render-heatmap__detail-pill--hot {
|
|
1245
1261
|
border-color: color-mix(in srgb, var(--red) 50%, var(--border));
|
|
1246
1262
|
color: var(--red);
|
|
1247
1263
|
}
|
|
1248
1264
|
|
|
1249
|
-
.
|
|
1265
|
+
.render-heatmap__detail-pill--persistent {
|
|
1250
1266
|
border-color: color-mix(in srgb, var(--amber) 55%, var(--border));
|
|
1251
1267
|
color: color-mix(in srgb, var(--amber) 80%, var(--text));
|
|
1252
1268
|
}
|
|
1253
1269
|
|
|
1254
|
-
.
|
|
1270
|
+
.render-heatmap__detail-pill--hydrated {
|
|
1255
1271
|
border-color: color-mix(in srgb, var(--teal) 55%, var(--border));
|
|
1256
1272
|
color: color-mix(in srgb, var(--teal) 80%, var(--text));
|
|
1257
1273
|
}
|
|
1258
1274
|
|
|
1259
|
-
.
|
|
1275
|
+
.render-heatmap__detail-pill--muted {
|
|
1260
1276
|
color: var(--text3);
|
|
1261
1277
|
border-color: var(--border);
|
|
1262
1278
|
}
|
|
1263
1279
|
|
|
1264
|
-
.
|
|
1265
|
-
font-size: 10px;
|
|
1266
|
-
font-weight: 500;
|
|
1267
|
-
text-transform: uppercase;
|
|
1268
|
-
letter-spacing: 0.4px;
|
|
1269
|
-
color: var(--text3);
|
|
1280
|
+
.render-heatmap__section-label {
|
|
1270
1281
|
margin-top: 8px;
|
|
1271
1282
|
margin-bottom: 4px;
|
|
1272
1283
|
}
|
|
1273
1284
|
|
|
1274
|
-
.
|
|
1285
|
+
.render-heatmap__file-row {
|
|
1286
|
+
display: flex;
|
|
1287
|
+
align-items: center;
|
|
1288
|
+
gap: 6px;
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
.render-heatmap__trigger-item {
|
|
1275
1292
|
background: var(--bg2);
|
|
1276
1293
|
border-radius: var(--radius);
|
|
1277
1294
|
padding: 4px 8px;
|
|
@@ -1279,6 +1296,20 @@ function formatTimestamp(t: number): string {
|
|
|
1279
1296
|
color: var(--text2);
|
|
1280
1297
|
}
|
|
1281
1298
|
|
|
1299
|
+
.render-heatmap__persistent-value {
|
|
1300
|
+
color: color-mix(in srgb, var(--amber) 80%, var(--text));
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
.render-heatmap__section-label--timeline {
|
|
1304
|
+
margin-top: var(--tracker-space-2);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
.render-heatmap__section-label-meta {
|
|
1308
|
+
font-weight: 400;
|
|
1309
|
+
text-transform: none;
|
|
1310
|
+
letter-spacing: 0;
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1282
1313
|
:deep(.tree-jump-btn) {
|
|
1283
1314
|
display: none;
|
|
1284
1315
|
padding: 0 4px;
|
|
@@ -1329,7 +1360,7 @@ function formatTimestamp(t: number): string {
|
|
|
1329
1360
|
max-width: 140px;
|
|
1330
1361
|
}
|
|
1331
1362
|
|
|
1332
|
-
.
|
|
1363
|
+
.render-heatmap__timeline-list {
|
|
1333
1364
|
display: flex;
|
|
1334
1365
|
flex-direction: column;
|
|
1335
1366
|
gap: 1px;
|
|
@@ -1341,49 +1372,49 @@ function formatTimestamp(t: number): string {
|
|
|
1341
1372
|
min-height: fit-content;
|
|
1342
1373
|
}
|
|
1343
1374
|
|
|
1344
|
-
.
|
|
1375
|
+
.render-heatmap__timeline-row {
|
|
1345
1376
|
display: flex;
|
|
1346
1377
|
align-items: center;
|
|
1347
1378
|
gap: 6px;
|
|
1348
1379
|
padding: 2px 0;
|
|
1349
|
-
font-size:
|
|
1350
|
-
border-bottom:
|
|
1380
|
+
font-size: var(--tracker-font-size-sm);
|
|
1381
|
+
border-bottom: var(--tracker-border-width) solid var(--border);
|
|
1351
1382
|
min-width: 0;
|
|
1352
1383
|
min-height: fit-content;
|
|
1353
1384
|
}
|
|
1354
1385
|
|
|
1355
|
-
.
|
|
1386
|
+
.render-heatmap__timeline-row:last-child {
|
|
1356
1387
|
border-bottom: none;
|
|
1357
1388
|
}
|
|
1358
1389
|
|
|
1359
|
-
.
|
|
1390
|
+
.render-heatmap__timeline-kind {
|
|
1360
1391
|
flex-shrink: 0;
|
|
1361
|
-
font-size:
|
|
1392
|
+
font-size: var(--tracker-font-size-xs);
|
|
1362
1393
|
font-weight: 500;
|
|
1363
1394
|
min-width: 40px;
|
|
1364
1395
|
}
|
|
1365
1396
|
|
|
1366
|
-
.
|
|
1397
|
+
.render-heatmap__timeline-kind.mount {
|
|
1367
1398
|
color: var(--teal);
|
|
1368
1399
|
}
|
|
1369
1400
|
|
|
1370
|
-
.
|
|
1401
|
+
.render-heatmap__timeline-kind.update {
|
|
1371
1402
|
color: var(--amber);
|
|
1372
1403
|
}
|
|
1373
1404
|
|
|
1374
|
-
.
|
|
1405
|
+
.render-heatmap__timeline-time {
|
|
1375
1406
|
flex-shrink: 0;
|
|
1376
1407
|
min-width: 52px;
|
|
1377
1408
|
color: var(--text3);
|
|
1378
1409
|
}
|
|
1379
1410
|
|
|
1380
|
-
.
|
|
1411
|
+
.render-heatmap__timeline-dur {
|
|
1381
1412
|
flex-shrink: 0;
|
|
1382
1413
|
min-width: 38px;
|
|
1383
1414
|
color: var(--text2);
|
|
1384
1415
|
}
|
|
1385
1416
|
|
|
1386
|
-
.
|
|
1417
|
+
.render-heatmap__timeline-trigger {
|
|
1387
1418
|
overflow: hidden;
|
|
1388
1419
|
text-overflow: ellipsis;
|
|
1389
1420
|
white-space: nowrap;
|
|
@@ -1392,19 +1423,23 @@ function formatTimestamp(t: number): string {
|
|
|
1392
1423
|
min-width: 0;
|
|
1393
1424
|
}
|
|
1394
1425
|
|
|
1395
|
-
.
|
|
1426
|
+
.render-heatmap__timeline-route {
|
|
1396
1427
|
flex-shrink: 0;
|
|
1428
|
+
margin-left: auto;
|
|
1397
1429
|
color: var(--text3);
|
|
1398
|
-
font-size:
|
|
1430
|
+
font-size: var(--tracker-font-size-xs);
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
.render-heatmap__compact-muted {
|
|
1434
|
+
padding: 2px 0;
|
|
1399
1435
|
}
|
|
1400
1436
|
|
|
1401
1437
|
@media (width <= 1180px) {
|
|
1402
|
-
.
|
|
1403
|
-
|
|
1438
|
+
.render-heatmap__roots-panel {
|
|
1439
|
+
display: none;
|
|
1404
1440
|
}
|
|
1405
1441
|
|
|
1406
|
-
.
|
|
1407
|
-
grid-column: 1 / -1;
|
|
1442
|
+
.render-heatmap__detail-panel {
|
|
1408
1443
|
max-height: 220px;
|
|
1409
1444
|
}
|
|
1410
1445
|
}
|