@react-perfscope/ui 0.3.0 → 0.4.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/dist/index.js CHANGED
@@ -72,6 +72,9 @@ var en = {
72
72
  sort: "Sort",
73
73
  sortChronological: "chronological",
74
74
  sortSeverity: "severity (worst first)",
75
+ filterPlaceholder: "Filter\u2026",
76
+ filterAria: "Filter signals",
77
+ filterNoMatches: "No signals match the filter.",
75
78
  groupBy: "Group by",
76
79
  groupChronological: "chronological",
77
80
  groupComponent: "component",
@@ -162,6 +165,9 @@ var ko = {
162
165
  sort: "\uC815\uB82C",
163
166
  sortChronological: "\uC2DC\uAC04\uC21C",
164
167
  sortSeverity: "\uC2EC\uAC01\uB3C4\uC21C (\uB192\uC740 \uAC83\uBD80\uD130)",
168
+ filterPlaceholder: "\uD544\uD130\u2026",
169
+ filterAria: "\uC2DC\uADF8\uB110 \uD544\uD130",
170
+ filterNoMatches: "\uD544\uD130\uC640 \uC77C\uCE58\uD558\uB294 \uC2DC\uADF8\uB110\uC774 \uC5C6\uC5B4\uC694.",
165
171
  groupBy: "\uADF8\uB8F9\uD654",
166
172
  groupChronological: "\uC2DC\uAC04\uC21C",
167
173
  groupComponent: "\uCEF4\uD3EC\uB10C\uD2B8",
@@ -1854,6 +1860,45 @@ function RenderInsights({ signals, onSelect }) {
1854
1860
  );
1855
1861
  }
1856
1862
 
1863
+ // src/filter.ts
1864
+ function signalSearchText(signal) {
1865
+ switch (signal.kind) {
1866
+ case "render": {
1867
+ const parts = [signal.component];
1868
+ if (signal.changedProps) parts.push(...signal.changedProps);
1869
+ if (signal.members) for (const m of signal.members) parts.push(m.component);
1870
+ return parts.join(" ").toLowerCase();
1871
+ }
1872
+ case "network":
1873
+ return signal.url.toLowerCase();
1874
+ case "web-vital":
1875
+ return signal.name.toLowerCase();
1876
+ case "interaction":
1877
+ return [signal.eventType, signal.target ?? ""].join(" ").toLowerCase();
1878
+ case "forced-reflow": {
1879
+ const f = signal.stack[0];
1880
+ return f ? [f.fnName ?? "", f.file].join(" ").toLowerCase() : "";
1881
+ }
1882
+ case "long-task": {
1883
+ const parts = [];
1884
+ if (signal.scripts)
1885
+ for (const s of signal.scripts) parts.push(s.sourceFunctionName, s.invoker, s.sourceURL);
1886
+ if (signal.attribution)
1887
+ for (const a of signal.attribution) parts.push(a.frame.fnName ?? "", a.frame.file);
1888
+ return parts.join(" ").toLowerCase();
1889
+ }
1890
+ case "layout-shift":
1891
+ return "layout-shift";
1892
+ default:
1893
+ return "";
1894
+ }
1895
+ }
1896
+ function signalMatchesFilter(signal, query) {
1897
+ const q = query.trim().toLowerCase();
1898
+ if (!q) return true;
1899
+ return signalSearchText(signal).includes(q);
1900
+ }
1901
+
1857
1902
  // src/panel.tsx
1858
1903
  import { Fragment as Fragment2, jsx as jsx5, jsxs as jsxs5 } from "preact/jsx-runtime";
1859
1904
  var RENDER_REASON_COLOR = {
@@ -2619,6 +2664,7 @@ function Panel(props) {
2619
2664
  const [expandedKey, setExpandedKey] = useState3(null);
2620
2665
  const [groupMode, setGroupMode] = useState3({});
2621
2666
  const [sortMode, setSortMode] = useState3({});
2667
+ const [filterText, setFilterText] = useState3({});
2622
2668
  const activeOverlayCount = useRef2(0);
2623
2669
  useEffect(() => () => hideAllOverlays(), []);
2624
2670
  function handleHover(signal) {
@@ -2825,7 +2871,21 @@ function Panel(props) {
2825
2871
  ]
2826
2872
  }
2827
2873
  )
2828
- ] })
2874
+ ] }),
2875
+ /* @__PURE__ */ jsx5(
2876
+ "input",
2877
+ {
2878
+ type: "text",
2879
+ "aria-label": t.filterAria,
2880
+ placeholder: t.filterPlaceholder,
2881
+ value: filterText[activeKind] ?? "",
2882
+ onInput: (e) => {
2883
+ setFilterText({ ...filterText, [activeKind]: e.target.value });
2884
+ setExpandedKey(null);
2885
+ },
2886
+ style: { marginLeft: "auto", background: "#1a1a1a", color: "#e6e6e6", border: "1px solid #2a2a2a", borderRadius: "4px", padding: "2px 6px", fontSize: "11px", width: "120px" }
2887
+ }
2888
+ )
2829
2889
  ] }),
2830
2890
  activeTab === "timeline" && /* @__PURE__ */ jsx5("div", { style: { flexGrow: 1, overflowY: "auto", paddingTop: "4px", paddingBottom: "24px" }, children: /* @__PURE__ */ jsx5(
2831
2891
  Timeline,
@@ -2846,9 +2906,7 @@ function Panel(props) {
2846
2906
  activeKind === "render" && activeTab !== "timeline" && /* @__PURE__ */ jsx5(
2847
2907
  RenderInsights,
2848
2908
  {
2849
- signals: grouped.render.flatMap(
2850
- (s) => s.kind === "render" ? s.members ?? [s] : []
2851
- ),
2909
+ signals: grouped.render.flatMap((s) => s.kind === "render" ? s.members ?? [s] : []).filter((s) => signalMatchesFilter(s, filterText.render ?? "")),
2852
2910
  onSelect: () => {
2853
2911
  setGroupMode({ ...groupMode, render: "component" });
2854
2912
  setExpandedKey(null);
@@ -2871,7 +2929,10 @@ function Panel(props) {
2871
2929
  }
2872
2930
  ),
2873
2931
  /* @__PURE__ */ jsx5("ul", { style: { listStyle: "none", margin: 0, padding: 0, overflowY: "auto", flexGrow: 1, display: activeTab === "timeline" ? "none" : void 0 }, children: activeKind && (() => {
2874
- const baseSignals = (sortMode[activeKind] ?? "chronological") === "severity" ? sortSignalsBySeverity(grouped[activeKind]) : grouped[activeKind];
2932
+ const filtered = grouped[activeKind].filter(
2933
+ (s) => signalMatchesFilter(s, filterText[activeKind] ?? "")
2934
+ );
2935
+ const baseSignals = (sortMode[activeKind] ?? "chronological") === "severity" ? sortSignalsBySeverity(filtered) : filtered;
2875
2936
  return groupSignals(baseSignals, groupMode[activeKind] ?? "chronological", activeKind);
2876
2937
  })().map((g, gi) => {
2877
2938
  const currentMode = groupMode[activeKind] ?? "chronological";
@@ -2929,7 +2990,8 @@ function Panel(props) {
2929
2990
  },
2930
2991
  key
2931
2992
  );
2932
- }) })
2993
+ }) }),
2994
+ activeKind && activeTab !== "timeline" && (filterText[activeKind] ?? "").trim() !== "" && grouped[activeKind].length > 0 && grouped[activeKind].every((s) => !signalMatchesFilter(s, filterText[activeKind] ?? "")) && /* @__PURE__ */ jsx5("div", { style: { padding: "12px 8px", fontSize: "11px", color: "#888" }, children: t.filterNoMatches })
2933
2995
  ] })
2934
2996
  ] });
2935
2997
  }