@mastra/playground-ui 51.3.2-alpha.0 → 51.4.0-alpha.2

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.
Files changed (138) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/Badge-DcllBqFg.cjs +125 -0
  3. package/dist/Badge-DcllBqFg.cjs.map +1 -0
  4. package/dist/Badge-uGehUtus.js +123 -0
  5. package/dist/Badge-uGehUtus.js.map +1 -0
  6. package/dist/components/Badge.cjs.js +1 -1
  7. package/dist/components/Badge.es.js +1 -1
  8. package/dist/components/DataList.cjs.js +4 -4
  9. package/dist/components/DataList.es.js +4 -4
  10. package/dist/components/EnvironmentVariablesEditor.cjs.js +1 -1
  11. package/dist/components/EnvironmentVariablesEditor.es.js +1 -1
  12. package/dist/components/ItemList.cjs.js +59 -40
  13. package/dist/components/ItemList.cjs.js.map +1 -1
  14. package/dist/components/ItemList.es.js +58 -41
  15. package/dist/components/ItemList.es.js.map +1 -1
  16. package/dist/components/LogsDataList.cjs.js +2 -2
  17. package/dist/components/LogsDataList.es.js +2 -2
  18. package/dist/components/ai/ask-user.cjs.js +3 -3
  19. package/dist/components/ai/ask-user.cjs.js.map +1 -1
  20. package/dist/components/ai/ask-user.es.js +3 -3
  21. package/dist/components/ai/ask-user.es.js.map +1 -1
  22. package/dist/components/ai/plan.cjs.js +3 -3
  23. package/dist/components/ai/plan.cjs.js.map +1 -1
  24. package/dist/components/ai/plan.es.js +3 -3
  25. package/dist/components/ai/plan.es.js.map +1 -1
  26. package/dist/{data-list-BOI8fRuk.js → data-list-C3tjx5Vb.js} +2 -2
  27. package/dist/{data-list-BOI8fRuk.js.map → data-list-C3tjx5Vb.js.map} +1 -1
  28. package/dist/{data-list-CCacNODd.cjs → data-list-CRDewYj9.cjs} +2 -2
  29. package/dist/{data-list-CCacNODd.cjs.map → data-list-CRDewYj9.cjs.map} +1 -1
  30. package/dist/{data-list-skeleton-DDO_OE14.js → data-list-skeleton-BCrkk6wG.js} +2 -2
  31. package/dist/{data-list-skeleton-DDO_OE14.js.map → data-list-skeleton-BCrkk6wG.js.map} +1 -1
  32. package/dist/{data-list-skeleton-BHBSIQHN.cjs → data-list-skeleton-CONfqzH2.cjs} +2 -2
  33. package/dist/{data-list-skeleton-BHBSIQHN.cjs.map → data-list-skeleton-CONfqzH2.cjs.map} +1 -1
  34. package/dist/{data-list-top-cell-BOXO5s7I.cjs → data-list-top-cell-DAztx3m8.cjs} +6 -1
  35. package/dist/data-list-top-cell-DAztx3m8.cjs.map +1 -0
  36. package/dist/{data-list-top-cell-CC5jjv5s.js → data-list-top-cell-hNkk6S-Q.js} +6 -2
  37. package/dist/data-list-top-cell-hNkk6S-Q.js.map +1 -0
  38. package/dist/domains/logs/components/logs-list-view.cjs.js +2 -2
  39. package/dist/domains/logs/components/logs-list-view.es.js +2 -2
  40. package/dist/domains/metrics/components/memory-card-view.cjs.js +1 -1
  41. package/dist/domains/metrics/components/memory-card-view.es.js +1 -1
  42. package/dist/domains/metrics/components/model-usage-cost-card-view.cjs.js +1 -1
  43. package/dist/domains/metrics/components/model-usage-cost-card-view.es.js +1 -1
  44. package/dist/domains/metrics/components/scores-card-view.cjs.js +1 -1
  45. package/dist/domains/metrics/components/scores-card-view.es.js +1 -1
  46. package/dist/domains/traces/components/format-hierarchical-spans.cjs.js +2 -1
  47. package/dist/domains/traces/components/format-hierarchical-spans.cjs.js.map +1 -1
  48. package/dist/domains/traces/components/format-hierarchical-spans.es.js +2 -1
  49. package/dist/domains/traces/components/format-hierarchical-spans.es.js.map +1 -1
  50. package/dist/domains/traces/components/timeline-name-col.cjs.js +10 -1
  51. package/dist/domains/traces/components/timeline-name-col.cjs.js.map +1 -1
  52. package/dist/domains/traces/components/timeline-name-col.es.js +10 -1
  53. package/dist/domains/traces/components/timeline-name-col.es.js.map +1 -1
  54. package/dist/domains/traces/components/trace-data-panel-view.cjs.js +17 -5
  55. package/dist/domains/traces/components/trace-data-panel-view.cjs.js.map +1 -1
  56. package/dist/domains/traces/components/trace-data-panel-view.es.js +17 -5
  57. package/dist/domains/traces/components/trace-data-panel-view.es.js.map +1 -1
  58. package/dist/domains/traces/components/traces-list-view.cjs.js +7 -9
  59. package/dist/domains/traces/components/traces-list-view.cjs.js.map +1 -1
  60. package/dist/domains/traces/components/traces-list-view.es.js +7 -9
  61. package/dist/domains/traces/components/traces-list-view.es.js.map +1 -1
  62. package/dist/domains/traces/hooks/use-trace-search.cjs.js +10 -4
  63. package/dist/domains/traces/hooks/use-trace-search.cjs.js.map +1 -1
  64. package/dist/domains/traces/hooks/use-trace-search.es.js +10 -4
  65. package/dist/domains/traces/hooks/use-trace-search.es.js.map +1 -1
  66. package/dist/domains/traces/trace-list-columns.cjs.js +1 -1
  67. package/dist/domains/traces/trace-list-columns.cjs.js.map +1 -1
  68. package/dist/domains/traces/trace-list-columns.es.js +1 -1
  69. package/dist/domains/traces/trace-list-columns.es.js.map +1 -1
  70. package/dist/domains/traces/types.cjs.js.map +1 -1
  71. package/dist/domains/traces/types.es.js.map +1 -1
  72. package/dist/ee/topics/components/topic-trace-summary-list.cjs.js +1 -1
  73. package/dist/ee/topics/components/topic-trace-summary-list.es.js +1 -1
  74. package/dist/hooks/use-scroll-to-first-highlight.cjs.js +44 -0
  75. package/dist/hooks/use-scroll-to-first-highlight.cjs.js.map +1 -0
  76. package/dist/hooks/use-scroll-to-first-highlight.d.ts +2 -0
  77. package/dist/hooks/use-scroll-to-first-highlight.es.js +40 -0
  78. package/dist/hooks/use-scroll-to-first-highlight.es.js.map +1 -0
  79. package/dist/hooks/use-text-highlight.cjs.js +49 -2
  80. package/dist/hooks/use-text-highlight.cjs.js.map +1 -1
  81. package/dist/hooks/use-text-highlight.es.js +48 -3
  82. package/dist/hooks/use-text-highlight.es.js.map +1 -1
  83. package/dist/{logs-data-list-Xayqbjw4.cjs → logs-data-list-D88JF2lo.cjs} +2 -2
  84. package/dist/{logs-data-list-Xayqbjw4.cjs.map → logs-data-list-D88JF2lo.cjs.map} +1 -1
  85. package/dist/{logs-data-list-DRXJ89IZ.js → logs-data-list-DnAXTwr7.js} +2 -2
  86. package/dist/{logs-data-list-DRXJ89IZ.js.map → logs-data-list-DnAXTwr7.js.map} +1 -1
  87. package/dist/src/domains/traces/components/format-hierarchical-spans.d.ts +1 -0
  88. package/dist/src/domains/traces/components/trace-data-panel-view.d.ts +1 -1
  89. package/dist/src/domains/traces/hooks/use-trace-search.d.ts +7 -0
  90. package/dist/src/domains/traces/types.d.ts +5 -0
  91. package/dist/src/ds/components/Badge/Badge.d.ts +86 -12
  92. package/dist/src/ds/components/Badge/badge.stories.d.ts +3 -0
  93. package/dist/src/ds/components/DataList/TracesDataList/traces-data-list.d.ts +2 -3
  94. package/dist/src/ds/components/DataList/data-list-cells.d.ts +5 -0
  95. package/dist/src/ds/components/ItemList/helpers.d.ts +8 -0
  96. package/dist/src/ds/components/ItemList/item-list-link-cell.d.ts +2 -1
  97. package/dist/src/ds/components/ItemList/item-list-row-button.d.ts +2 -1
  98. package/dist/src/ds/components/ai/plan/plan.d.ts +1 -1
  99. package/dist/src/hooks/use-scroll-to-first-highlight.d.ts +20 -0
  100. package/dist/src/hooks/use-text-highlight.d.ts +18 -0
  101. package/dist/src/test/highlight-api.d.ts +6 -4
  102. package/dist/style.css +364 -219
  103. package/dist/{traces-data-list-BLZgf-Es.cjs → traces-data-list-COksp2d4.cjs} +12 -13
  104. package/dist/traces-data-list-COksp2d4.cjs.map +1 -0
  105. package/dist/{traces-data-list-DmXGwe4Q.js → traces-data-list-c5I-8hwt.js} +12 -13
  106. package/dist/traces-data-list-c5I-8hwt.js.map +1 -0
  107. package/dist/use-text-highlight.css +8 -0
  108. package/package.json +7 -7
  109. package/theme.css +53 -0
  110. package/dist/Badge-BlJpI3fY.cjs +0 -57
  111. package/dist/Badge-BlJpI3fY.cjs.map +0 -1
  112. package/dist/Badge-woV6OD8k.js +0 -55
  113. package/dist/Badge-woV6OD8k.js.map +0 -1
  114. package/dist/chip-9P9t0dvN.cjs +0 -68
  115. package/dist/chip-9P9t0dvN.cjs.map +0 -1
  116. package/dist/chip-Bg0-95sX.js +0 -66
  117. package/dist/chip-Bg0-95sX.js.map +0 -1
  118. package/dist/components/Chip.cjs.js +0 -27
  119. package/dist/components/Chip.cjs.js.map +0 -1
  120. package/dist/components/Chip.d.ts +0 -2
  121. package/dist/components/Chip.es.js +0 -22
  122. package/dist/components/Chip.es.js.map +0 -1
  123. package/dist/components/StatusBadge.cjs.js +0 -76
  124. package/dist/components/StatusBadge.cjs.js.map +0 -1
  125. package/dist/components/StatusBadge.d.ts +0 -2
  126. package/dist/components/StatusBadge.es.js +0 -72
  127. package/dist/components/StatusBadge.es.js.map +0 -1
  128. package/dist/data-list-top-cell-BOXO5s7I.cjs.map +0 -1
  129. package/dist/data-list-top-cell-CC5jjv5s.js.map +0 -1
  130. package/dist/src/ds/components/Chip/chip.d.ts +0 -8
  131. package/dist/src/ds/components/Chip/chip.stories.d.ts +0 -11
  132. package/dist/src/ds/components/Chip/chips-group.d.ts +0 -2
  133. package/dist/src/ds/components/Chip/index.d.ts +0 -2
  134. package/dist/src/ds/components/StatusBadge/StatusBadge.d.ts +0 -13
  135. package/dist/src/ds/components/StatusBadge/index.d.ts +0 -2
  136. package/dist/src/ds/components/StatusBadge/status-badge.stories.d.ts +0 -8
  137. package/dist/traces-data-list-BLZgf-Es.cjs.map +0 -1
  138. package/dist/traces-data-list-DmXGwe4Q.js.map +0 -1
@@ -2,30 +2,67 @@ import { useState } from 'react';
2
2
  import { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect.es.js';
3
3
 
4
4
  import '../use-text-highlight.css';const HIGHLIGHT_NAME = "search-result";
5
+ const INDIRECT_HIGHLIGHT_NAME = "search-result-indirect";
5
6
  const MIN_SEARCH_LENGTH = 2;
6
7
  const INCLUDED_SELECTOR = "[data-highlight]";
8
+ const INDIRECT_SELECTOR = "[data-highlight-indirect]";
7
9
  function escapeRegExp(value) {
8
10
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
9
11
  }
12
+ function findFirstMatchTextNode(root, search) {
13
+ const regex = new RegExp(escapeRegExp(search), "iu");
14
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
15
+ acceptNode(node) {
16
+ const parent = node.parentElement;
17
+ return parent.closest(`${INCLUDED_SELECTOR}, ${INDIRECT_SELECTOR}`) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
18
+ }
19
+ });
20
+ while (walker.nextNode()) {
21
+ const textNode = walker.currentNode;
22
+ const parent = textNode.parentElement;
23
+ if (parent.closest(INDIRECT_SELECTOR)) {
24
+ if (textNode.data.length > 0) return textNode;
25
+ continue;
26
+ }
27
+ if (regex.test(textNode.data)) return textNode;
28
+ }
29
+ return null;
30
+ }
10
31
  function useTextHighlight(search) {
11
32
  const [root, setRoot] = useState(null);
12
33
  useIsomorphicLayoutEffect(() => {
13
34
  if (!root || search.trim().length < MIN_SEARCH_LENGTH || typeof CSS === "undefined" || !("highlights" in CSS) || typeof StaticRange === "undefined") {
14
35
  CSS?.highlights?.delete(HIGHLIGHT_NAME);
36
+ CSS?.highlights?.delete(INDIRECT_HIGHLIGHT_NAME);
15
37
  return;
16
38
  }
17
39
  let animationFrame = null;
18
40
  const updateHighlight = () => {
19
41
  const ranges = [];
42
+ const indirectRanges = [];
20
43
  const regex = new RegExp(escapeRegExp(search), "giu");
21
44
  const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
22
45
  acceptNode(node) {
23
46
  const parent = node.parentElement;
24
- return parent.closest(INCLUDED_SELECTOR) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
47
+ return parent.closest(`${INCLUDED_SELECTOR}, ${INDIRECT_SELECTOR}`) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
25
48
  }
26
49
  });
27
50
  while (walker.nextNode()) {
28
51
  const textNode = walker.currentNode;
52
+ const parent = textNode.parentElement;
53
+ if (parent.closest(INDIRECT_SELECTOR)) {
54
+ if (textNode.data.length > 0) {
55
+ indirectRanges.push(
56
+ new StaticRange({
57
+ startContainer: textNode,
58
+ startOffset: 0,
59
+ endContainer: textNode,
60
+ endOffset: textNode.data.length
61
+ })
62
+ );
63
+ }
64
+ continue;
65
+ }
29
66
  regex.lastIndex = 0;
30
67
  let match;
31
68
  while ((match = regex.exec(textNode.data)) !== null) {
@@ -40,6 +77,7 @@ function useTextHighlight(search) {
40
77
  }
41
78
  }
42
79
  CSS.highlights.set(HIGHLIGHT_NAME, new Highlight(...ranges));
80
+ CSS.highlights.set(INDIRECT_HIGHLIGHT_NAME, new Highlight(...indirectRanges));
43
81
  };
44
82
  const scheduleUpdate = () => {
45
83
  if (animationFrame !== null) cancelAnimationFrame(animationFrame);
@@ -50,15 +88,22 @@ function useTextHighlight(search) {
50
88
  };
51
89
  updateHighlight();
52
90
  const observer = new MutationObserver(scheduleUpdate);
53
- observer.observe(root, { subtree: true, childList: true, characterData: true });
91
+ observer.observe(root, {
92
+ subtree: true,
93
+ childList: true,
94
+ characterData: true,
95
+ attributes: true,
96
+ attributeFilter: ["data-highlight", "data-highlight-indirect"]
97
+ });
54
98
  return () => {
55
99
  observer.disconnect();
56
100
  if (animationFrame !== null) cancelAnimationFrame(animationFrame);
57
101
  CSS.highlights.delete(HIGHLIGHT_NAME);
102
+ CSS.highlights.delete(INDIRECT_HIGHLIGHT_NAME);
58
103
  };
59
104
  }, [root, search]);
60
105
  return { ref: setRoot };
61
106
  }
62
107
 
63
- export { useTextHighlight };
108
+ export { MIN_SEARCH_LENGTH, findFirstMatchTextNode, useTextHighlight };
64
109
  //# sourceMappingURL=use-text-highlight.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-text-highlight.es.js","sources":["../../src/hooks/use-text-highlight.ts"],"sourcesContent":["import { useState } from 'react';\nimport type { RefCallback } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\nimport './use-text-highlight.css';\n\n/** Single registry entry, so only one search surface can be highlighted at a time. */\nconst HIGHLIGHT_NAME = 'search-result';\n\n/**\n * A single character matches almost everywhere, which paints noise instead of results.\n * Highlighting only starts once the term is discriminating enough.\n */\nconst MIN_SEARCH_LENGTH = 2;\n\n/**\n * Opt-in marker: only text inside a `data-highlight` subtree can be painted. Highlighting\n * is a claim about which text is searchable, so surfaces state it explicitly rather than\n * having every piece of surrounding chrome remember to opt out.\n */\nconst INCLUDED_SELECTOR = '[data-highlight]';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport interface UseTextHighlightResult<TElement extends HTMLElement> {\n ref: RefCallback<TElement>;\n}\n\n/**\n * Paints every occurrence of `search` inside the referenced subtree using the CSS Custom\n * Highlight API. Only text under an element carrying `data-highlight` is painted, so a\n * surface names its searchable regions and everything else — headers, labels, metadata —\n * is left alone by default. The DOM is never mutated — no wrapper elements are injected — so text\n * selection, copy/paste and virtualised renderers are unaffected. Styling lives in\n * `use-text-highlight.css` (`::highlight(search-result)`).\n *\n * Terms shorter than two characters are ignored — they match too much to be useful.\n * Matching is case-insensitive and literal (the term is escaped, not a pattern). The\n * subtree is re-scanned on content changes, coalesced to one scan per frame. Browsers\n * without the API simply render nothing highlighted.\n */\nexport function useTextHighlight<TElement extends HTMLElement = HTMLElement>(\n search: string,\n): UseTextHighlightResult<TElement> {\n const [root, setRoot] = useState<TElement | null>(null);\n\n useIsomorphicLayoutEffect(() => {\n if (\n !root ||\n search.trim().length < MIN_SEARCH_LENGTH ||\n typeof CSS === 'undefined' ||\n !('highlights' in CSS) ||\n typeof StaticRange === 'undefined'\n ) {\n CSS?.highlights?.delete(HIGHLIGHT_NAME);\n return;\n }\n\n let animationFrame: number | null = null;\n\n const updateHighlight = () => {\n const ranges: StaticRange[] = [];\n const regex = new RegExp(escapeRegExp(search), 'giu');\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {\n acceptNode(node) {\n // Inside a rooted walker every text node has a parent element.\n const parent = node.parentElement as HTMLElement;\n return parent.closest(INCLUDED_SELECTOR) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;\n },\n });\n\n while (walker.nextNode()) {\n const textNode = walker.currentNode as Text;\n regex.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(textNode.data)) !== null) {\n ranges.push(\n new StaticRange({\n startContainer: textNode,\n startOffset: match.index,\n endContainer: textNode,\n endOffset: match.index + match[0].length,\n }),\n );\n }\n }\n\n CSS.highlights.set(HIGHLIGHT_NAME, new Highlight(...ranges));\n };\n\n const scheduleUpdate = () => {\n if (animationFrame !== null) cancelAnimationFrame(animationFrame);\n\n animationFrame = requestAnimationFrame(() => {\n animationFrame = null;\n updateHighlight();\n });\n };\n\n updateHighlight();\n\n const observer = new MutationObserver(scheduleUpdate);\n observer.observe(root, { subtree: true, childList: true, characterData: true });\n\n return () => {\n observer.disconnect();\n if (animationFrame !== null) cancelAnimationFrame(animationFrame);\n CSS.highlights.delete(HIGHLIGHT_NAME);\n };\n }, [root, search]);\n\n return { ref: setRoot };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"use-text-highlight.es.js","sources":["../../src/hooks/use-text-highlight.ts"],"sourcesContent":["import { useState } from 'react';\nimport type { RefCallback } from 'react';\n\nimport { useIsomorphicLayoutEffect } from './use-isomorphic-layout-effect';\nimport './use-text-highlight.css';\n\n/** Single registry entry, so only one search surface can be highlighted at a time. */\nconst HIGHLIGHT_NAME = 'search-result';\n\n/**\n * Second registry entry for text that carries no occurrence of the term itself, but stands\n * for something elsewhere that does — a span name whose match hides in its metadata. Painted\n * in its own color so the two claims stay distinguishable.\n */\nconst INDIRECT_HIGHLIGHT_NAME = 'search-result-indirect';\n\n/**\n * A single character matches almost everywhere, which paints noise instead of results.\n * Highlighting only starts once the term is discriminating enough.\n */\nexport const MIN_SEARCH_LENGTH = 2;\n\n/**\n * Opt-in marker: only text inside a `data-highlight` subtree can be painted. Highlighting\n * is a claim about which text is searchable, so surfaces state it explicitly rather than\n * having every piece of surrounding chrome remember to opt out.\n */\nconst INCLUDED_SELECTOR = '[data-highlight]';\n\n/**\n * Opt-in marker for the indirect highlight: the whole text of such a subtree is painted\n * while a query is active, regardless of what the term is. Marking is the caller's decision\n * — it knows why the row survived the filter, this hook only knows the term.\n */\nconst INDIRECT_SELECTOR = '[data-highlight-indirect]';\n\nfunction escapeRegExp(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * The first text node the highlighter would paint under `root` for `search`, or `null`.\n * Mirrors the walker below exactly: only `data-highlight` / `data-highlight-indirect`\n * subtrees count; indirect text is painted whole, so any non-empty text node in one is a\n * hit; direct text needs a literal, case-insensitive occurrence of the term. Colocated\n * here so the scroll target (`useScrollToFirstHighlight`) can't drift from the paint.\n */\nexport function findFirstMatchTextNode(root: HTMLElement, search: string): Text | null {\n const regex = new RegExp(escapeRegExp(search), 'iu');\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {\n acceptNode(node) {\n const parent = node.parentElement as HTMLElement;\n return parent.closest(`${INCLUDED_SELECTOR}, ${INDIRECT_SELECTOR}`)\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_REJECT;\n },\n });\n\n while (walker.nextNode()) {\n const textNode = walker.currentNode as Text;\n const parent = textNode.parentElement as HTMLElement;\n\n if (parent.closest(INDIRECT_SELECTOR)) {\n if (textNode.data.length > 0) return textNode;\n continue;\n }\n\n if (regex.test(textNode.data)) return textNode;\n }\n\n return null;\n}\n\nexport interface UseTextHighlightResult<TElement extends HTMLElement> {\n ref: RefCallback<TElement>;\n}\n\n/**\n * Paints every occurrence of `search` inside the referenced subtree using the CSS Custom\n * Highlight API. Only text under an element carrying `data-highlight` is painted, so a\n * surface names its searchable regions and everything else — headers, labels, metadata —\n * is left alone by default. The DOM is never mutated — no wrapper elements are injected — so text\n * selection, copy/paste and virtualised renderers are unaffected. Styling lives in\n * `use-text-highlight.css` (`::highlight(search-result)`).\n *\n * Text under `data-highlight-indirect` is painted in full, in a second color\n * (`::highlight(search-result-indirect)`), whatever the term is. That is for labels standing\n * in for a match that lives somewhere not on screen — a span name whose hit is in its\n * metadata. It wins over `data-highlight` when both apply, so a text is never painted twice.\n *\n * Terms shorter than two characters are ignored — they match too much to be useful.\n * Matching is case-insensitive and literal (the term is escaped, not a pattern). The\n * subtree is re-scanned on content changes, coalesced to one scan per frame. Browsers\n * without the API simply render nothing highlighted.\n */\nexport function useTextHighlight<TElement extends HTMLElement = HTMLElement>(\n search: string,\n): UseTextHighlightResult<TElement> {\n const [root, setRoot] = useState<TElement | null>(null);\n\n useIsomorphicLayoutEffect(() => {\n if (\n !root ||\n search.trim().length < MIN_SEARCH_LENGTH ||\n typeof CSS === 'undefined' ||\n !('highlights' in CSS) ||\n typeof StaticRange === 'undefined'\n ) {\n CSS?.highlights?.delete(HIGHLIGHT_NAME);\n CSS?.highlights?.delete(INDIRECT_HIGHLIGHT_NAME);\n return;\n }\n\n let animationFrame: number | null = null;\n\n const updateHighlight = () => {\n const ranges: StaticRange[] = [];\n const indirectRanges: StaticRange[] = [];\n const regex = new RegExp(escapeRegExp(search), 'giu');\n\n const walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {\n acceptNode(node) {\n // Inside a rooted walker every text node has a parent element.\n const parent = node.parentElement as HTMLElement;\n return parent.closest(`${INCLUDED_SELECTOR}, ${INDIRECT_SELECTOR}`)\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_REJECT;\n },\n });\n\n while (walker.nextNode()) {\n const textNode = walker.currentNode as Text;\n const parent = textNode.parentElement as HTMLElement;\n\n // The indirect claim is about the whole text, so there is nothing to search for\n // inside it: the term lives in the payload this text stands for, not in the text.\n if (parent.closest(INDIRECT_SELECTOR)) {\n if (textNode.data.length > 0) {\n indirectRanges.push(\n new StaticRange({\n startContainer: textNode,\n startOffset: 0,\n endContainer: textNode,\n endOffset: textNode.data.length,\n }),\n );\n }\n continue;\n }\n\n regex.lastIndex = 0;\n\n let match: RegExpExecArray | null;\n while ((match = regex.exec(textNode.data)) !== null) {\n ranges.push(\n new StaticRange({\n startContainer: textNode,\n startOffset: match.index,\n endContainer: textNode,\n endOffset: match.index + match[0].length,\n }),\n );\n }\n }\n\n CSS.highlights.set(HIGHLIGHT_NAME, new Highlight(...ranges));\n CSS.highlights.set(INDIRECT_HIGHLIGHT_NAME, new Highlight(...indirectRanges));\n };\n\n const scheduleUpdate = () => {\n if (animationFrame !== null) cancelAnimationFrame(animationFrame);\n\n animationFrame = requestAnimationFrame(() => {\n animationFrame = null;\n updateHighlight();\n });\n };\n\n updateHighlight();\n\n // The opt-in attributes are watched too: a region can change which highlight it claims\n // while its text stays put, and that alone must repaint it.\n const observer = new MutationObserver(scheduleUpdate);\n observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n attributeFilter: ['data-highlight', 'data-highlight-indirect'],\n });\n\n return () => {\n observer.disconnect();\n if (animationFrame !== null) cancelAnimationFrame(animationFrame);\n CSS.highlights.delete(HIGHLIGHT_NAME);\n CSS.highlights.delete(INDIRECT_HIGHLIGHT_NAME);\n };\n }, [root, search]);\n\n return { ref: setRoot };\n}\n"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const dataListTopCell = require('./data-list-top-cell-BOXO5s7I.cjs');
3
+ const dataListTopCell = require('./data-list-top-cell-DAztx3m8.cjs');
4
4
  const jsxRuntime = require('react/jsx-runtime');
5
5
  const icons_AgentIcon = require('./icons/AgentIcon.cjs.js');
6
6
  const icons_ToolsIcon = require('./icons/ToolsIcon.cjs.js');
@@ -78,4 +78,4 @@ const LogsDataList = Object.assign(dataListTopCell.DataListRoot, {
78
78
  });
79
79
 
80
80
  exports.LogsDataList = LogsDataList;
81
- //# sourceMappingURL=logs-data-list-Xayqbjw4.cjs.map
81
+ //# sourceMappingURL=logs-data-list-D88JF2lo.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs-data-list-Xayqbjw4.cjs","sources":["../src/ds/components/LogsDataList/logs-data-list-cells.tsx","../src/ds/components/LogsDataList/logs-data-list.tsx"],"sourcesContent":["import { DataListCell, DataListTextCell } from '../DataList/data-list-cells';\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';\nimport { AgentIcon } from '@/ds/icons/AgentIcon';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { WorkflowIcon } from '@/ds/icons/WorkflowIcon';\nimport { cn } from '@/lib/utils';\n\nconst LEVEL_CONFIG: Record<LogLevel, { label: string; color: string }> = {\n debug: { label: 'DEBUG', color: '#71717a' },\n info: { label: 'INFO', color: '#60a5fa' },\n warn: { label: 'WARN', color: '#facc15' },\n error: { label: 'ERROR', color: '#f87171' },\n fatal: { label: 'FATAL', color: '#dc2626' },\n};\n\n// ---------------------------------------------------------------------------\n// LevelCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListLevelCellProps {\n level: LogLevel;\n}\n\nexport function LogsDataListLevelCell({ level }: LogsDataListLevelCellProps) {\n const config = LEVEL_CONFIG[level];\n\n return (\n <DataListCell>\n <span className=\"text-ui-sm font-semibold uppercase\" style={{ color: config.color }}>\n {config.label}\n </span>\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// EntityCell\n// ---------------------------------------------------------------------------\n\nfunction EntityTypeIcon({ entityType, className }: { entityType: string; className?: string }) {\n const iconClass = cn('size-3.5 shrink-0 text-neutral2', className);\n const normalizedEntityType = entityType.toLowerCase();\n\n switch (normalizedEntityType) {\n case 'agent':\n return <AgentIcon className={iconClass} aria-hidden />;\n case 'workflow':\n case 'workflow_run':\n return <WorkflowIcon className={iconClass} aria-hidden />;\n case 'tool':\n return <ToolsIcon className={iconClass} aria-hidden />;\n default:\n return null;\n }\n}\n\nexport interface LogsDataListEntityCellProps {\n entityType?: string | null;\n entityName?: string | null;\n}\n\nexport function LogsDataListEntityCell({ entityType, entityName }: LogsDataListEntityCellProps) {\n const type = entityType ?? '';\n\n return (\n <DataListCell className=\"flex min-w-0 items-center gap-2\">\n <EntityTypeIcon entityType={type} />\n {entityName ? <span className=\"text-ui-smd min-w-0 truncate\">{entityName}</span> : '-'}\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// MessageCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListMessageCellProps {\n message: string;\n}\n\nexport function LogsDataListMessageCell({ message }: LogsDataListMessageCellProps) {\n return <DataListCell className=\"text-ui-smd text-neutral4 min-w-0 truncate font-mono\">{message}</DataListCell>;\n}\n\n// ---------------------------------------------------------------------------\n// DataCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListDataCellProps {\n data?: Record<string, unknown> | null;\n}\n\nexport function LogsDataListDataCell({ data }: LogsDataListDataCellProps) {\n if (!data || Object.keys(data).length === 0) {\n return <DataListCell>{null}</DataListCell>;\n }\n\n const summary = Object.entries(data)\n .map(([k, v]) => {\n if (typeof v === 'string') return `${k}: ${v}`;\n try {\n return `${k}: ${JSON.stringify(v)}`;\n } catch {\n return `${k}: <unserializable>`;\n }\n })\n .join(', ');\n\n return <DataListTextCell font=\"mono\">{summary}</DataListTextCell>;\n}\n","import { DataListDateCell, DataListTimeCell } from '../DataList/data-list-cells';\nimport { DataListNextPageLoading } from '../DataList/data-list-next-page-loading';\nimport { DataListNoMatch } from '../DataList/data-list-no-match';\nimport { DataListRoot } from '../DataList/data-list-root';\nimport { DataListRowButton } from '../DataList/data-list-row-button';\nimport { DataListRowLink } from '../DataList/data-list-row-link';\nimport { DataListRowWrapper } from '../DataList/data-list-row-wrapper';\nimport { DataListSpacer } from '../DataList/data-list-spacer';\nimport { DataListTop } from '../DataList/data-list-top';\nimport { DataListTopCell, DataListTopCellWithTooltip, DataListTopCellSmart } from '../DataList/data-list-top-cell';\nimport {\n LogsDataListLevelCell,\n LogsDataListEntityCell,\n LogsDataListMessageCell,\n LogsDataListDataCell,\n} from './logs-data-list-cells';\n\nexport const LogsDataList = Object.assign(DataListRoot, {\n Top: DataListTop,\n TopCell: DataListTopCell,\n TopCellWithTooltip: DataListTopCellWithTooltip,\n TopCellSmart: DataListTopCellSmart,\n RowWrapper: DataListRowWrapper,\n RowButton: DataListRowButton,\n RowLink: DataListRowLink,\n Spacer: DataListSpacer,\n NoMatch: DataListNoMatch,\n DateCell: DataListDateCell,\n TimeCell: DataListTimeCell,\n LevelCell: LogsDataListLevelCell,\n EntityCell: LogsDataListEntityCell,\n MessageCell: LogsDataListMessageCell,\n DataCell: LogsDataListDataCell,\n NextPageLoading: DataListNextPageLoading,\n});\n"],"names":["jsx","DataListCell","cn","AgentIcon","WorkflowIcon","ToolsIcon","jsxs","DataListTextCell","DataListRoot","DataListTop","DataListTopCell","DataListTopCellWithTooltip","DataListTopCellSmart","DataListRowWrapper","DataListRowButton","DataListRowLink","DataListSpacer","DataListNoMatch","DataListDateCell","DataListTimeCell","DataListNextPageLoading"],"mappings":";;;;;;;;;AAOA,MAAM,YAAA,GAAmE;AAAA,EACvE,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA,EAAU;AAAA,EAC1C,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAO,SAAA,EAAU;AAAA,EACxC,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAO,SAAA,EAAU;AAAA,EACxC,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA,EAAU;AAAA,EAC1C,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA;AAClC,CAAA;AAUO,SAAS,qBAAA,CAAsB,EAAE,KAAA,EAAM,EAA+B;AAC3E,EAAA,MAAM,MAAA,GAAS,aAAa,KAAK,CAAA;AAEjC,EAAA,uBACEA,cAAA,CAACC,4BAAA,EAAA,EACC,QAAA,kBAAAD,cAAA,CAAC,MAAA,EAAA,EAAK,WAAU,oCAAA,EAAqC,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAM,EAC/E,QAAA,EAAA,MAAA,CAAO,OACV,CAAA,EACF,CAAA;AAEJ;AAMA,SAAS,cAAA,CAAe,EAAE,UAAA,EAAY,SAAA,EAAU,EAA+C;AAC7F,EAAA,MAAM,SAAA,GAAYE,WAAA,CAAG,iCAAA,EAAmC,SAAS,CAAA;AACjE,EAAA,MAAM,oBAAA,GAAuB,WAAW,WAAA,EAAY;AAEpD,EAAA,QAAQ,oBAAA;AAAsB,IAC5B,KAAK,OAAA;AACH,MAAA,uBAAOF,cAAA,CAACG,yBAAA,EAAA,EAAU,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACtD,KAAK,UAAA;AAAA,IACL,KAAK,cAAA;AACH,MAAA,uBAAOH,cAAA,CAACI,+BAAA,EAAA,EAAa,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACzD,KAAK,MAAA;AACH,MAAA,uBAAOJ,cAAA,CAACK,yBAAA,EAAA,EAAU,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACtD;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAOO,SAAS,sBAAA,CAAuB,EAAE,UAAA,EAAY,UAAA,EAAW,EAAgC;AAC9F,EAAA,MAAM,OAAO,UAAA,IAAc,EAAA;AAE3B,EAAA,uBACEC,eAAA,CAACL,4BAAA,EAAA,EAAa,SAAA,EAAU,iCAAA,EACtB,QAAA,EAAA;AAAA,oBAAAD,cAAA,CAAC,cAAA,EAAA,EAAe,YAAY,IAAA,EAAM,CAAA;AAAA,IACjC,6BAAaA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,sBAAW,CAAA,GAAU;AAAA,GAAA,EACrF,CAAA;AAEJ;AAUO,SAAS,uBAAA,CAAwB,EAAE,OAAA,EAAQ,EAAiC;AACjF,EAAA,uBAAOA,cAAA,CAACC,4BAAA,EAAA,EAAa,SAAA,EAAU,sDAAA,EAAwD,QAAA,EAAA,OAAA,EAAQ,CAAA;AACjG;AAUO,SAAS,oBAAA,CAAqB,EAAE,IAAA,EAAK,EAA8B;AACxE,EAAA,IAAI,CAAC,IAAA,IAAQ,MAAA,CAAO,KAAK,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AAC3C,IAAA,uBAAOD,cAAA,CAACC,gCAAc,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,EAC7B;AAEA,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,CAChC,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM;AACf,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,SAAiB,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAC5C,IAAA,IAAI;AACF,MAAA,OAAO,GAAG,CAAC,CAAA,EAAA,EAAK,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAA;AAAA,IACnC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,GAAG,CAAC,CAAA,kBAAA,CAAA;AAAA,IACb;AAAA,EACF,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,uBAAOD,cAAA,CAACO,gCAAA,EAAA,EAAiB,IAAA,EAAK,MAAA,EAAQ,QAAA,EAAA,OAAA,EAAQ,CAAA;AAChD;;AC5FO,MAAM,YAAA,GAAe,MAAA,CAAO,MAAA,CAAOC,4BAAA,EAAc;AAAA,EACtD,GAAA,EAAKC,2BAAA;AAAA,EACL,OAAA,EAASC,+BAAA;AAAA,EACT,kBAAA,EAAoBC,0CAAA;AAAA,EACpB,YAAA,EAAcC,oCAAA;AAAA,EACd,UAAA,EAAYC,kCAAA;AAAA,EACZ,SAAA,EAAWC,iCAAA;AAAA,EACX,OAAA,EAASC,+BAAA;AAAA,EACT,MAAA,EAAQC,8BAAA;AAAA,EACR,OAAA,EAASC,+BAAA;AAAA,EACT,QAAA,EAAUC,gCAAA;AAAA,EACV,QAAA,EAAUC,gCAAA;AAAA,EACV,SAAA,EAAW,qBAAA;AAAA,EACX,UAAA,EAAY,sBAAA;AAAA,EACZ,WAAA,EAAa,uBAAA;AAAA,EACb,QAAA,EAAU,oBAAA;AAAA,EACV,eAAA,EAAiBC;AACnB,CAAC;;;;"}
1
+ {"version":3,"file":"logs-data-list-D88JF2lo.cjs","sources":["../src/ds/components/LogsDataList/logs-data-list-cells.tsx","../src/ds/components/LogsDataList/logs-data-list.tsx"],"sourcesContent":["import { DataListCell, DataListTextCell } from '../DataList/data-list-cells';\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';\nimport { AgentIcon } from '@/ds/icons/AgentIcon';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { WorkflowIcon } from '@/ds/icons/WorkflowIcon';\nimport { cn } from '@/lib/utils';\n\nconst LEVEL_CONFIG: Record<LogLevel, { label: string; color: string }> = {\n debug: { label: 'DEBUG', color: '#71717a' },\n info: { label: 'INFO', color: '#60a5fa' },\n warn: { label: 'WARN', color: '#facc15' },\n error: { label: 'ERROR', color: '#f87171' },\n fatal: { label: 'FATAL', color: '#dc2626' },\n};\n\n// ---------------------------------------------------------------------------\n// LevelCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListLevelCellProps {\n level: LogLevel;\n}\n\nexport function LogsDataListLevelCell({ level }: LogsDataListLevelCellProps) {\n const config = LEVEL_CONFIG[level];\n\n return (\n <DataListCell>\n <span className=\"text-ui-sm font-semibold uppercase\" style={{ color: config.color }}>\n {config.label}\n </span>\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// EntityCell\n// ---------------------------------------------------------------------------\n\nfunction EntityTypeIcon({ entityType, className }: { entityType: string; className?: string }) {\n const iconClass = cn('size-3.5 shrink-0 text-neutral2', className);\n const normalizedEntityType = entityType.toLowerCase();\n\n switch (normalizedEntityType) {\n case 'agent':\n return <AgentIcon className={iconClass} aria-hidden />;\n case 'workflow':\n case 'workflow_run':\n return <WorkflowIcon className={iconClass} aria-hidden />;\n case 'tool':\n return <ToolsIcon className={iconClass} aria-hidden />;\n default:\n return null;\n }\n}\n\nexport interface LogsDataListEntityCellProps {\n entityType?: string | null;\n entityName?: string | null;\n}\n\nexport function LogsDataListEntityCell({ entityType, entityName }: LogsDataListEntityCellProps) {\n const type = entityType ?? '';\n\n return (\n <DataListCell className=\"flex min-w-0 items-center gap-2\">\n <EntityTypeIcon entityType={type} />\n {entityName ? <span className=\"text-ui-smd min-w-0 truncate\">{entityName}</span> : '-'}\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// MessageCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListMessageCellProps {\n message: string;\n}\n\nexport function LogsDataListMessageCell({ message }: LogsDataListMessageCellProps) {\n return <DataListCell className=\"text-ui-smd text-neutral4 min-w-0 truncate font-mono\">{message}</DataListCell>;\n}\n\n// ---------------------------------------------------------------------------\n// DataCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListDataCellProps {\n data?: Record<string, unknown> | null;\n}\n\nexport function LogsDataListDataCell({ data }: LogsDataListDataCellProps) {\n if (!data || Object.keys(data).length === 0) {\n return <DataListCell>{null}</DataListCell>;\n }\n\n const summary = Object.entries(data)\n .map(([k, v]) => {\n if (typeof v === 'string') return `${k}: ${v}`;\n try {\n return `${k}: ${JSON.stringify(v)}`;\n } catch {\n return `${k}: <unserializable>`;\n }\n })\n .join(', ');\n\n return <DataListTextCell font=\"mono\">{summary}</DataListTextCell>;\n}\n","import { DataListDateCell, DataListTimeCell } from '../DataList/data-list-cells';\nimport { DataListNextPageLoading } from '../DataList/data-list-next-page-loading';\nimport { DataListNoMatch } from '../DataList/data-list-no-match';\nimport { DataListRoot } from '../DataList/data-list-root';\nimport { DataListRowButton } from '../DataList/data-list-row-button';\nimport { DataListRowLink } from '../DataList/data-list-row-link';\nimport { DataListRowWrapper } from '../DataList/data-list-row-wrapper';\nimport { DataListSpacer } from '../DataList/data-list-spacer';\nimport { DataListTop } from '../DataList/data-list-top';\nimport { DataListTopCell, DataListTopCellWithTooltip, DataListTopCellSmart } from '../DataList/data-list-top-cell';\nimport {\n LogsDataListLevelCell,\n LogsDataListEntityCell,\n LogsDataListMessageCell,\n LogsDataListDataCell,\n} from './logs-data-list-cells';\n\nexport const LogsDataList = Object.assign(DataListRoot, {\n Top: DataListTop,\n TopCell: DataListTopCell,\n TopCellWithTooltip: DataListTopCellWithTooltip,\n TopCellSmart: DataListTopCellSmart,\n RowWrapper: DataListRowWrapper,\n RowButton: DataListRowButton,\n RowLink: DataListRowLink,\n Spacer: DataListSpacer,\n NoMatch: DataListNoMatch,\n DateCell: DataListDateCell,\n TimeCell: DataListTimeCell,\n LevelCell: LogsDataListLevelCell,\n EntityCell: LogsDataListEntityCell,\n MessageCell: LogsDataListMessageCell,\n DataCell: LogsDataListDataCell,\n NextPageLoading: DataListNextPageLoading,\n});\n"],"names":["jsx","DataListCell","cn","AgentIcon","WorkflowIcon","ToolsIcon","jsxs","DataListTextCell","DataListRoot","DataListTop","DataListTopCell","DataListTopCellWithTooltip","DataListTopCellSmart","DataListRowWrapper","DataListRowButton","DataListRowLink","DataListSpacer","DataListNoMatch","DataListDateCell","DataListTimeCell","DataListNextPageLoading"],"mappings":";;;;;;;;;AAOA,MAAM,YAAA,GAAmE;AAAA,EACvE,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA,EAAU;AAAA,EAC1C,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAO,SAAA,EAAU;AAAA,EACxC,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAQ,OAAO,SAAA,EAAU;AAAA,EACxC,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA,EAAU;AAAA,EAC1C,KAAA,EAAO,EAAE,KAAA,EAAO,OAAA,EAAS,OAAO,SAAA;AAClC,CAAA;AAUO,SAAS,qBAAA,CAAsB,EAAE,KAAA,EAAM,EAA+B;AAC3E,EAAA,MAAM,MAAA,GAAS,aAAa,KAAK,CAAA;AAEjC,EAAA,uBACEA,cAAA,CAACC,4BAAA,EAAA,EACC,QAAA,kBAAAD,cAAA,CAAC,MAAA,EAAA,EAAK,WAAU,oCAAA,EAAqC,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,CAAO,KAAA,EAAM,EAC/E,QAAA,EAAA,MAAA,CAAO,OACV,CAAA,EACF,CAAA;AAEJ;AAMA,SAAS,cAAA,CAAe,EAAE,UAAA,EAAY,SAAA,EAAU,EAA+C;AAC7F,EAAA,MAAM,SAAA,GAAYE,WAAA,CAAG,iCAAA,EAAmC,SAAS,CAAA;AACjE,EAAA,MAAM,oBAAA,GAAuB,WAAW,WAAA,EAAY;AAEpD,EAAA,QAAQ,oBAAA;AAAsB,IAC5B,KAAK,OAAA;AACH,MAAA,uBAAOF,cAAA,CAACG,yBAAA,EAAA,EAAU,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACtD,KAAK,UAAA;AAAA,IACL,KAAK,cAAA;AACH,MAAA,uBAAOH,cAAA,CAACI,+BAAA,EAAA,EAAa,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACzD,KAAK,MAAA;AACH,MAAA,uBAAOJ,cAAA,CAACK,yBAAA,EAAA,EAAU,SAAA,EAAW,SAAA,EAAW,eAAW,IAAA,EAAC,CAAA;AAAA,IACtD;AACE,MAAA,OAAO,IAAA;AAAA;AAEb;AAOO,SAAS,sBAAA,CAAuB,EAAE,UAAA,EAAY,UAAA,EAAW,EAAgC;AAC9F,EAAA,MAAM,OAAO,UAAA,IAAc,EAAA;AAE3B,EAAA,uBACEC,eAAA,CAACL,4BAAA,EAAA,EAAa,SAAA,EAAU,iCAAA,EACtB,QAAA,EAAA;AAAA,oBAAAD,cAAA,CAAC,cAAA,EAAA,EAAe,YAAY,IAAA,EAAM,CAAA;AAAA,IACjC,6BAAaA,cAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,8BAAA,EAAgC,sBAAW,CAAA,GAAU;AAAA,GAAA,EACrF,CAAA;AAEJ;AAUO,SAAS,uBAAA,CAAwB,EAAE,OAAA,EAAQ,EAAiC;AACjF,EAAA,uBAAOA,cAAA,CAACC,4BAAA,EAAA,EAAa,SAAA,EAAU,sDAAA,EAAwD,QAAA,EAAA,OAAA,EAAQ,CAAA;AACjG;AAUO,SAAS,oBAAA,CAAqB,EAAE,IAAA,EAAK,EAA8B;AACxE,EAAA,IAAI,CAAC,IAAA,IAAQ,MAAA,CAAO,KAAK,IAAI,CAAA,CAAE,WAAW,CAAA,EAAG;AAC3C,IAAA,uBAAOD,cAAA,CAACC,gCAAc,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,EAC7B;AAEA,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,IAAI,CAAA,CAChC,IAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM;AACf,IAAA,IAAI,OAAO,CAAA,KAAM,QAAA,SAAiB,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA,CAAA;AAC5C,IAAA,IAAI;AACF,MAAA,OAAO,GAAG,CAAC,CAAA,EAAA,EAAK,IAAA,CAAK,SAAA,CAAU,CAAC,CAAC,CAAA,CAAA;AAAA,IACnC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,GAAG,CAAC,CAAA,kBAAA,CAAA;AAAA,IACb;AAAA,EACF,CAAC,CAAA,CACA,IAAA,CAAK,IAAI,CAAA;AAEZ,EAAA,uBAAOD,cAAA,CAACO,gCAAA,EAAA,EAAiB,IAAA,EAAK,MAAA,EAAQ,QAAA,EAAA,OAAA,EAAQ,CAAA;AAChD;;AC5FO,MAAM,YAAA,GAAe,MAAA,CAAO,MAAA,CAAOC,4BAAA,EAAc;AAAA,EACtD,GAAA,EAAKC,2BAAA;AAAA,EACL,OAAA,EAASC,+BAAA;AAAA,EACT,kBAAA,EAAoBC,0CAAA;AAAA,EACpB,YAAA,EAAcC,oCAAA;AAAA,EACd,UAAA,EAAYC,kCAAA;AAAA,EACZ,SAAA,EAAWC,iCAAA;AAAA,EACX,OAAA,EAASC,+BAAA;AAAA,EACT,MAAA,EAAQC,8BAAA;AAAA,EACR,OAAA,EAASC,+BAAA;AAAA,EACT,QAAA,EAAUC,gCAAA;AAAA,EACV,QAAA,EAAUC,gCAAA;AAAA,EACV,SAAA,EAAW,qBAAA;AAAA,EACX,UAAA,EAAY,sBAAA;AAAA,EACZ,WAAA,EAAa,uBAAA;AAAA,EACb,QAAA,EAAU,oBAAA;AAAA,EACV,eAAA,EAAiBC;AACnB,CAAC;;;;"}
@@ -1,4 +1,4 @@
1
- import { a as DataListCell, b as DataListTextCell, D as DataListRoot, c as DataListNextPageLoading, e as DataListTimeCell, f as DataListDateCell, g as DataListNoMatch, h as DataListSpacer, i as DataListRowLink, j as DataListRowButton, k as DataListRowWrapper, l as DataListTopCellSmart, m as DataListTopCellWithTooltip, n as DataListTopCell, o as DataListTop } from './data-list-top-cell-CC5jjv5s.js';
1
+ import { a as DataListCell, b as DataListTextCell, D as DataListRoot, c as DataListNextPageLoading, e as DataListTimeCell, f as DataListDateCell, g as DataListNoMatch, h as DataListSpacer, i as DataListRowLink, j as DataListRowButton, k as DataListRowWrapper, l as DataListTopCellSmart, m as DataListTopCellWithTooltip, n as DataListTopCell, o as DataListTop } from './data-list-top-cell-hNkk6S-Q.js';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { AgentIcon } from './icons/AgentIcon.es.js';
4
4
  import { ToolsIcon } from './icons/ToolsIcon.es.js';
@@ -76,4 +76,4 @@ const LogsDataList = Object.assign(DataListRoot, {
76
76
  });
77
77
 
78
78
  export { LogsDataList as L };
79
- //# sourceMappingURL=logs-data-list-DRXJ89IZ.js.map
79
+ //# sourceMappingURL=logs-data-list-DnAXTwr7.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs-data-list-DRXJ89IZ.js","sources":["../src/ds/components/LogsDataList/logs-data-list-cells.tsx","../src/ds/components/LogsDataList/logs-data-list.tsx"],"sourcesContent":["import { DataListCell, DataListTextCell } from '../DataList/data-list-cells';\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';\nimport { AgentIcon } from '@/ds/icons/AgentIcon';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { WorkflowIcon } from '@/ds/icons/WorkflowIcon';\nimport { cn } from '@/lib/utils';\n\nconst LEVEL_CONFIG: Record<LogLevel, { label: string; color: string }> = {\n debug: { label: 'DEBUG', color: '#71717a' },\n info: { label: 'INFO', color: '#60a5fa' },\n warn: { label: 'WARN', color: '#facc15' },\n error: { label: 'ERROR', color: '#f87171' },\n fatal: { label: 'FATAL', color: '#dc2626' },\n};\n\n// ---------------------------------------------------------------------------\n// LevelCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListLevelCellProps {\n level: LogLevel;\n}\n\nexport function LogsDataListLevelCell({ level }: LogsDataListLevelCellProps) {\n const config = LEVEL_CONFIG[level];\n\n return (\n <DataListCell>\n <span className=\"text-ui-sm font-semibold uppercase\" style={{ color: config.color }}>\n {config.label}\n </span>\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// EntityCell\n// ---------------------------------------------------------------------------\n\nfunction EntityTypeIcon({ entityType, className }: { entityType: string; className?: string }) {\n const iconClass = cn('size-3.5 shrink-0 text-neutral2', className);\n const normalizedEntityType = entityType.toLowerCase();\n\n switch (normalizedEntityType) {\n case 'agent':\n return <AgentIcon className={iconClass} aria-hidden />;\n case 'workflow':\n case 'workflow_run':\n return <WorkflowIcon className={iconClass} aria-hidden />;\n case 'tool':\n return <ToolsIcon className={iconClass} aria-hidden />;\n default:\n return null;\n }\n}\n\nexport interface LogsDataListEntityCellProps {\n entityType?: string | null;\n entityName?: string | null;\n}\n\nexport function LogsDataListEntityCell({ entityType, entityName }: LogsDataListEntityCellProps) {\n const type = entityType ?? '';\n\n return (\n <DataListCell className=\"flex min-w-0 items-center gap-2\">\n <EntityTypeIcon entityType={type} />\n {entityName ? <span className=\"text-ui-smd min-w-0 truncate\">{entityName}</span> : '-'}\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// MessageCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListMessageCellProps {\n message: string;\n}\n\nexport function LogsDataListMessageCell({ message }: LogsDataListMessageCellProps) {\n return <DataListCell className=\"text-ui-smd text-neutral4 min-w-0 truncate font-mono\">{message}</DataListCell>;\n}\n\n// ---------------------------------------------------------------------------\n// DataCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListDataCellProps {\n data?: Record<string, unknown> | null;\n}\n\nexport function LogsDataListDataCell({ data }: LogsDataListDataCellProps) {\n if (!data || Object.keys(data).length === 0) {\n return <DataListCell>{null}</DataListCell>;\n }\n\n const summary = Object.entries(data)\n .map(([k, v]) => {\n if (typeof v === 'string') return `${k}: ${v}`;\n try {\n return `${k}: ${JSON.stringify(v)}`;\n } catch {\n return `${k}: <unserializable>`;\n }\n })\n .join(', ');\n\n return <DataListTextCell font=\"mono\">{summary}</DataListTextCell>;\n}\n","import { DataListDateCell, DataListTimeCell } from '../DataList/data-list-cells';\nimport { DataListNextPageLoading } from '../DataList/data-list-next-page-loading';\nimport { DataListNoMatch } from '../DataList/data-list-no-match';\nimport { DataListRoot } from '../DataList/data-list-root';\nimport { DataListRowButton } from '../DataList/data-list-row-button';\nimport { DataListRowLink } from '../DataList/data-list-row-link';\nimport { DataListRowWrapper } from '../DataList/data-list-row-wrapper';\nimport { DataListSpacer } from '../DataList/data-list-spacer';\nimport { DataListTop } from '../DataList/data-list-top';\nimport { DataListTopCell, DataListTopCellWithTooltip, DataListTopCellSmart } from '../DataList/data-list-top-cell';\nimport {\n LogsDataListLevelCell,\n LogsDataListEntityCell,\n LogsDataListMessageCell,\n LogsDataListDataCell,\n} from './logs-data-list-cells';\n\nexport const LogsDataList = Object.assign(DataListRoot, {\n Top: DataListTop,\n TopCell: DataListTopCell,\n TopCellWithTooltip: DataListTopCellWithTooltip,\n TopCellSmart: DataListTopCellSmart,\n RowWrapper: DataListRowWrapper,\n RowButton: DataListRowButton,\n RowLink: DataListRowLink,\n Spacer: DataListSpacer,\n NoMatch: DataListNoMatch,\n DateCell: DataListDateCell,\n TimeCell: DataListTimeCell,\n LevelCell: LogsDataListLevelCell,\n EntityCell: LogsDataListEntityCell,\n MessageCell: LogsDataListMessageCell,\n DataCell: LogsDataListDataCell,\n NextPageLoading: DataListNextPageLoading,\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logs-data-list-DnAXTwr7.js","sources":["../src/ds/components/LogsDataList/logs-data-list-cells.tsx","../src/ds/components/LogsDataList/logs-data-list.tsx"],"sourcesContent":["import { DataListCell, DataListTextCell } from '../DataList/data-list-cells';\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'fatal';\nimport { AgentIcon } from '@/ds/icons/AgentIcon';\nimport { ToolsIcon } from '@/ds/icons/ToolsIcon';\nimport { WorkflowIcon } from '@/ds/icons/WorkflowIcon';\nimport { cn } from '@/lib/utils';\n\nconst LEVEL_CONFIG: Record<LogLevel, { label: string; color: string }> = {\n debug: { label: 'DEBUG', color: '#71717a' },\n info: { label: 'INFO', color: '#60a5fa' },\n warn: { label: 'WARN', color: '#facc15' },\n error: { label: 'ERROR', color: '#f87171' },\n fatal: { label: 'FATAL', color: '#dc2626' },\n};\n\n// ---------------------------------------------------------------------------\n// LevelCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListLevelCellProps {\n level: LogLevel;\n}\n\nexport function LogsDataListLevelCell({ level }: LogsDataListLevelCellProps) {\n const config = LEVEL_CONFIG[level];\n\n return (\n <DataListCell>\n <span className=\"text-ui-sm font-semibold uppercase\" style={{ color: config.color }}>\n {config.label}\n </span>\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// EntityCell\n// ---------------------------------------------------------------------------\n\nfunction EntityTypeIcon({ entityType, className }: { entityType: string; className?: string }) {\n const iconClass = cn('size-3.5 shrink-0 text-neutral2', className);\n const normalizedEntityType = entityType.toLowerCase();\n\n switch (normalizedEntityType) {\n case 'agent':\n return <AgentIcon className={iconClass} aria-hidden />;\n case 'workflow':\n case 'workflow_run':\n return <WorkflowIcon className={iconClass} aria-hidden />;\n case 'tool':\n return <ToolsIcon className={iconClass} aria-hidden />;\n default:\n return null;\n }\n}\n\nexport interface LogsDataListEntityCellProps {\n entityType?: string | null;\n entityName?: string | null;\n}\n\nexport function LogsDataListEntityCell({ entityType, entityName }: LogsDataListEntityCellProps) {\n const type = entityType ?? '';\n\n return (\n <DataListCell className=\"flex min-w-0 items-center gap-2\">\n <EntityTypeIcon entityType={type} />\n {entityName ? <span className=\"text-ui-smd min-w-0 truncate\">{entityName}</span> : '-'}\n </DataListCell>\n );\n}\n\n// ---------------------------------------------------------------------------\n// MessageCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListMessageCellProps {\n message: string;\n}\n\nexport function LogsDataListMessageCell({ message }: LogsDataListMessageCellProps) {\n return <DataListCell className=\"text-ui-smd text-neutral4 min-w-0 truncate font-mono\">{message}</DataListCell>;\n}\n\n// ---------------------------------------------------------------------------\n// DataCell\n// ---------------------------------------------------------------------------\n\nexport interface LogsDataListDataCellProps {\n data?: Record<string, unknown> | null;\n}\n\nexport function LogsDataListDataCell({ data }: LogsDataListDataCellProps) {\n if (!data || Object.keys(data).length === 0) {\n return <DataListCell>{null}</DataListCell>;\n }\n\n const summary = Object.entries(data)\n .map(([k, v]) => {\n if (typeof v === 'string') return `${k}: ${v}`;\n try {\n return `${k}: ${JSON.stringify(v)}`;\n } catch {\n return `${k}: <unserializable>`;\n }\n })\n .join(', ');\n\n return <DataListTextCell font=\"mono\">{summary}</DataListTextCell>;\n}\n","import { DataListDateCell, DataListTimeCell } from '../DataList/data-list-cells';\nimport { DataListNextPageLoading } from '../DataList/data-list-next-page-loading';\nimport { DataListNoMatch } from '../DataList/data-list-no-match';\nimport { DataListRoot } from '../DataList/data-list-root';\nimport { DataListRowButton } from '../DataList/data-list-row-button';\nimport { DataListRowLink } from '../DataList/data-list-row-link';\nimport { DataListRowWrapper } from '../DataList/data-list-row-wrapper';\nimport { DataListSpacer } from '../DataList/data-list-spacer';\nimport { DataListTop } from '../DataList/data-list-top';\nimport { DataListTopCell, DataListTopCellWithTooltip, DataListTopCellSmart } from '../DataList/data-list-top-cell';\nimport {\n LogsDataListLevelCell,\n LogsDataListEntityCell,\n LogsDataListMessageCell,\n LogsDataListDataCell,\n} from './logs-data-list-cells';\n\nexport const LogsDataList = Object.assign(DataListRoot, {\n Top: DataListTop,\n TopCell: DataListTopCell,\n TopCellWithTooltip: DataListTopCellWithTooltip,\n TopCellSmart: DataListTopCellSmart,\n RowWrapper: DataListRowWrapper,\n RowButton: DataListRowButton,\n RowLink: DataListRowLink,\n Spacer: DataListSpacer,\n NoMatch: DataListNoMatch,\n DateCell: DataListDateCell,\n TimeCell: DataListTimeCell,\n LevelCell: LogsDataListLevelCell,\n EntityCell: LogsDataListEntityCell,\n MessageCell: LogsDataListMessageCell,\n DataCell: LogsDataListDataCell,\n NextPageLoading: DataListNextPageLoading,\n});\n"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@ type TimelineSpan = {
7
7
  startedAt: Date | string;
8
8
  endedAt?: Date | string | null;
9
9
  parentSpanId?: string | null;
10
+ matchedInPayloadOnly?: boolean;
10
11
  };
11
12
  /**
12
13
  * When `anchorSpanId` is provided, that span is treated as the displayed root
@@ -18,7 +18,7 @@ export interface TraceDataPanelViewProps {
18
18
  onClose: () => void;
19
19
  onSpanSelect?: (spanId: string | undefined) => void;
20
20
  onEvaluateTrace?: () => void;
21
- /** When set, a "Save as Dataset Item" button appears; the consumer owns the dialog. */
21
+ /** When set, an "Add full trace to dataset" button appears; the consumer owns the dialog. */
22
22
  onSaveAsDatasetItem?: (args: {
23
23
  traceId: string;
24
24
  rootSpanId: string | undefined;
@@ -5,6 +5,13 @@ export interface UseTraceSearchResult {
5
5
  setQuery: (query: string) => void;
6
6
  /** Rows matching the deferred query. An empty query returns the input array reference. */
7
7
  results: SearchableSpan[];
8
+ /**
9
+ * Spans that matched somewhere other than their name — in `metadata`, `attributes` or
10
+ * `error`. Their row shows no visible occurrence of the term, so the surface needs to say
11
+ * why it is there. Ancestors kept only to preserve the hierarchy are not in here: they did
12
+ * not match at all. Empty while the query is empty.
13
+ */
14
+ payloadOnlyMatchIds: Set<string>;
8
15
  /** True while the deferred value is behind `query` (the list is still catching up). */
9
16
  isPending: boolean;
10
17
  }
@@ -25,6 +25,11 @@ export type UISpan = {
25
25
  endTime?: string;
26
26
  spans?: UISpan[];
27
27
  parentSpanId?: string | null;
28
+ /**
29
+ * Set when the span survived the active search because of its payload, not its name — the
30
+ * timeline paints such a row differently since the term is nowhere on it.
31
+ */
32
+ matchedInPayloadOnly?: boolean;
28
33
  };
29
34
  export type UISpanStyle = {
30
35
  icon?: ReactNode;
@@ -1,13 +1,87 @@
1
- import { VariantProps } from 'class-variance-authority';
2
- import { default as React } from 'react';
3
- declare const badgeVariants: (props?: ({
4
- variant?: "default" | "error" | "success" | "info" | "warning" | null | undefined;
5
- size?: "sm" | "xs" | "md" | null | undefined;
6
- withIcon?: boolean | null | undefined;
7
- } & import('class-variance-authority/types').ClassProp) | undefined) => string;
8
- export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, Omit<VariantProps<typeof badgeVariants>, 'withIcon'> {
9
- icon?: React.ReactNode;
10
- children?: React.ReactNode;
11
- }
12
- export declare const Badge: ({ icon, variant, size, className, children, ...props }: BadgeProps) => React.JSX.Element;
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
+ export type BadgeEmphasis = 'default' | 'muted';
3
+ export type BadgeIndicator = 'dot' | 'pulse';
4
+ declare const badgeToneStyles: {
5
+ neutral: {
6
+ default: string;
7
+ muted: string;
8
+ indicator: string;
9
+ };
10
+ green: {
11
+ default: string;
12
+ muted: string;
13
+ indicator: string;
14
+ };
15
+ red: {
16
+ default: string;
17
+ muted: string;
18
+ indicator: string;
19
+ };
20
+ blue: {
21
+ default: string;
22
+ muted: string;
23
+ indicator: string;
24
+ };
25
+ yellow: {
26
+ default: string;
27
+ muted: string;
28
+ indicator: string;
29
+ };
30
+ purple: {
31
+ default: string;
32
+ muted: string;
33
+ indicator: string;
34
+ };
35
+ orange: {
36
+ default: string;
37
+ muted: string;
38
+ indicator: string;
39
+ };
40
+ cyan: {
41
+ default: string;
42
+ muted: string;
43
+ indicator: string;
44
+ };
45
+ pink: {
46
+ default: string;
47
+ muted: string;
48
+ indicator: string;
49
+ };
50
+ };
51
+ export type BadgeVariant = keyof typeof badgeToneStyles;
52
+ declare const badgeSizeStyles: {
53
+ xs: {
54
+ badge: string;
55
+ withoutLeadingVisual: string;
56
+ withLeadingVisual: string;
57
+ indicator: string;
58
+ };
59
+ sm: {
60
+ badge: string;
61
+ withoutLeadingVisual: string;
62
+ withLeadingVisual: string;
63
+ indicator: string;
64
+ };
65
+ md: {
66
+ badge: string;
67
+ withoutLeadingVisual: string;
68
+ withLeadingVisual: string;
69
+ indicator: string;
70
+ };
71
+ };
72
+ export type BadgeSize = keyof typeof badgeSizeStyles;
73
+ type BadgeLeadingVisual = {
74
+ icon?: ReactNode;
75
+ indicator?: never;
76
+ } | {
77
+ icon?: never;
78
+ indicator?: BadgeIndicator;
79
+ };
80
+ export type BadgeProps = HTMLAttributes<HTMLSpanElement> & BadgeLeadingVisual & {
81
+ variant?: BadgeVariant;
82
+ emphasis?: BadgeEmphasis;
83
+ size?: BadgeSize;
84
+ children?: ReactNode;
85
+ };
86
+ export declare const Badge: ({ icon, indicator, variant, emphasis, size, className, children, ...props }: BadgeProps) => import("react").JSX.Element;
13
87
  export {};
@@ -3,5 +3,8 @@ import { Badge } from './Badge';
3
3
  declare const meta: Meta<typeof Badge>;
4
4
  export default meta;
5
5
  type Story = StoryObj<typeof Badge>;
6
+ export declare const StyleComparison: Story;
6
7
  export declare const Matrix: Story;
8
+ export declare const Indicators: Story;
9
+ export declare const Emphasis: Story;
7
10
  export declare const Sizes: Story;
@@ -1,5 +1,5 @@
1
1
  import { ComponentProps } from 'react';
2
- import { DataListDateCell, DataListIdCell, DataListTimeCell } from '../data-list-cells';
2
+ import { DataListCreatedCell, DataListIdCell } from '../data-list-cells';
3
3
  import { DataListNextPageLoading } from '../data-list-next-page-loading';
4
4
  import { DataListNoMatch } from '../data-list-no-match';
5
5
  import { DataListRoot } from '../data-list-root';
@@ -24,8 +24,7 @@ export declare const TracesDataList: typeof TracesDataListRoot & {
24
24
  SubHeading: typeof DataListSubHeading;
25
25
  Spacer: typeof DataListSpacer;
26
26
  IdCell: typeof DataListIdCell;
27
- DateCell: typeof DataListDateCell;
28
- TimeCell: typeof DataListTimeCell;
27
+ CreatedCell: typeof DataListCreatedCell;
29
28
  NameCell: typeof TracesDataListNameCell;
30
29
  InputCell: typeof TracesDataListInputCell;
31
30
  EntityCell: typeof TracesDataListEntityCell;
@@ -67,6 +67,11 @@ export interface DataListDateCellProps {
67
67
  }
68
68
  /** Compact date cell — `Today` or `MMM dd` (e.g. `May 19`). */
69
69
  export declare function DataListDateCell({ timestamp }: DataListDateCellProps): import("react").JSX.Element;
70
+ export interface DataListCreatedCellProps {
71
+ timestamp: Date | string;
72
+ }
73
+ /** Combined date + time cell — `MMM dd h:mm:ss a` (e.g. `Aug 31 1:07:47 pm`), no milliseconds. */
74
+ export declare function DataListCreatedCell({ timestamp }: DataListCreatedCellProps): import("react").JSX.Element;
70
75
  export interface DataListTimeCellProps {
71
76
  timestamp: Date | string;
72
77
  }
@@ -5,6 +5,14 @@ type getToItemFnParams = {
5
5
  id: string | undefined;
6
6
  update: (id: string) => void;
7
7
  };
8
+ export declare const ITEM_LIST_VERSION_STATUS_LABELS: {
9
+ readonly latest: "Latest version";
10
+ readonly deleted: "Deleted in this version";
11
+ };
12
+ export declare function getItemListVersionStatusLabel({ isLatest, isDeleted, }: {
13
+ isLatest?: boolean;
14
+ isDeleted?: boolean;
15
+ }): string | undefined;
8
16
  export declare function getToNextItemFn({ entries, id, update }: getToItemFnParams): (() => void) | undefined;
9
17
  export declare function getToPreviousItemFn({ entries, id, update }: getToItemFnParams): (() => void) | undefined;
10
18
  export {};
@@ -4,5 +4,6 @@ export type ItemListLinkCellProps = {
4
4
  className?: string;
5
5
  href: string;
6
6
  LinkComponent: LinkComponent;
7
+ tooltip?: React.ReactNode;
7
8
  };
8
- export declare function ItemListLinkCell({ children, href, className, LinkComponent: Link }: ItemListLinkCellProps): import("react").JSX.Element;
9
+ export declare function ItemListLinkCell({ children, href, className, LinkComponent: Link, tooltip }: ItemListLinkCellProps): import("react").JSX.Element;
@@ -7,5 +7,6 @@ export type ItemListRowButtonProps = React.ComponentPropsWithoutRef<'button'> &
7
7
  columns?: ItemListColumn[];
8
8
  className?: string;
9
9
  disabled?: boolean;
10
+ tooltip?: React.ReactNode;
10
11
  };
11
- export declare function ItemListRowButton({ item, isFeatured, onClick, children, columns, className, disabled, ...props }: ItemListRowButtonProps): import("react").JSX.Element;
12
+ export declare function ItemListRowButton({ item, isFeatured, onClick, children, columns, className, disabled, tooltip, ...props }: ItemListRowButtonProps): import("react").JSX.Element;
@@ -12,7 +12,7 @@ export type PlanLabelProps = ComponentProps<'div'>;
12
12
  export declare function PlanLabel({ children, className, ...props }: PlanLabelProps): import("react").JSX.Element;
13
13
  export type PlanHeaderActionsProps = ComponentProps<'div'>;
14
14
  export declare function PlanHeaderActions({ children, className, ...props }: PlanHeaderActionsProps): import("react").JSX.Element;
15
- export type PlanStatusProps = Omit<ComponentProps<typeof Badge>, 'icon' | 'size'>;
15
+ export type PlanStatusProps = Omit<ComponentProps<typeof Badge>, 'icon' | 'indicator' | 'size'>;
16
16
  export declare function PlanStatus({ children, variant, ...props }: PlanStatusProps): import("react").JSX.Element;
17
17
  export interface PlanCopyButtonProps extends Omit<ComponentProps<typeof Button>, 'aria-label' | 'children' | 'onClick' | 'size' | 'tooltip' | 'type' | 'variant'> {
18
18
  content: string;
@@ -0,0 +1,20 @@
1
+ import { RefCallback } from 'react';
2
+ export interface UseScrollToFirstHighlightResult<TElement extends HTMLElement> {
3
+ ref: RefCallback<TElement>;
4
+ }
5
+ /**
6
+ * Scrolls the first text-highlight match inside the referenced subtree into view. The
7
+ * CSS Custom Highlight API paints ranges without wrapping DOM nodes, so there is no
8
+ * `<mark>` to scroll to — instead the first text node `useTextHighlight` would paint is
9
+ * located (same matching rules) and its parent element is brought into view.
10
+ *
11
+ * Content often arrives after the effect runs: the span payload loads async, and when a
12
+ * different span is selected the panel briefly still shows the previous span's DOM. So a
13
+ * MutationObserver stays attached for the effect's lifetime (rescans coalesced to one per
14
+ * frame) and re-scrolls whenever the previously scrolled-to node is gone or no longer
15
+ * contains the term — i.e. the content it scrolled to was replaced. While the matched
16
+ * node stays put, mutations never re-scroll, so the user can scroll freely afterwards.
17
+ * Pass `resetKey` to re-trigger the scroll for the same query, e.g. when a different
18
+ * span is selected.
19
+ */
20
+ export declare function useScrollToFirstHighlight<TElement extends HTMLElement = HTMLElement>(search: string, resetKey?: unknown): UseScrollToFirstHighlightResult<TElement>;
@@ -1,4 +1,17 @@
1
1
  import { RefCallback } from 'react';
2
+ /**
3
+ * A single character matches almost everywhere, which paints noise instead of results.
4
+ * Highlighting only starts once the term is discriminating enough.
5
+ */
6
+ export declare const MIN_SEARCH_LENGTH = 2;
7
+ /**
8
+ * The first text node the highlighter would paint under `root` for `search`, or `null`.
9
+ * Mirrors the walker below exactly: only `data-highlight` / `data-highlight-indirect`
10
+ * subtrees count; indirect text is painted whole, so any non-empty text node in one is a
11
+ * hit; direct text needs a literal, case-insensitive occurrence of the term. Colocated
12
+ * here so the scroll target (`useScrollToFirstHighlight`) can't drift from the paint.
13
+ */
14
+ export declare function findFirstMatchTextNode(root: HTMLElement, search: string): Text | null;
2
15
  export interface UseTextHighlightResult<TElement extends HTMLElement> {
3
16
  ref: RefCallback<TElement>;
4
17
  }
@@ -10,6 +23,11 @@ export interface UseTextHighlightResult<TElement extends HTMLElement> {
10
23
  * selection, copy/paste and virtualised renderers are unaffected. Styling lives in
11
24
  * `use-text-highlight.css` (`::highlight(search-result)`).
12
25
  *
26
+ * Text under `data-highlight-indirect` is painted in full, in a second color
27
+ * (`::highlight(search-result-indirect)`), whatever the term is. That is for labels standing
28
+ * in for a match that lives somewhere not on screen — a span name whose hit is in its
29
+ * metadata. It wins over `data-highlight` when both apply, so a text is never painted twice.
30
+ *
13
31
  * Terms shorter than two characters are ignored — they match too much to be useful.
14
32
  * Matching is case-insensitive and literal (the term is escaped, not a pattern). The
15
33
  * subtree is re-scanned on content changes, coalesced to one scan per frame. Browsers
@@ -19,10 +19,12 @@ export interface HighlightApiHarness {
19
19
  set: ReturnType<typeof vi.fn>;
20
20
  delete: ReturnType<typeof vi.fn>;
21
21
  };
22
- /** The text covered by the ranges of the most recent registration. */
23
- highlightedText: () => string[] | undefined;
24
- /** The elements owning the highlighted text of the most recent registration. */
25
- highlightedIn: () => (HTMLElement | null)[];
22
+ /** The text covered by the most recent registration under `name` (the direct one by default). */
23
+ highlightedText: (name?: string) => string[] | undefined;
24
+ /** The elements owning that text. */
25
+ highlightedIn: (name?: string) => (HTMLElement | null)[];
26
+ /** How many times `name` was registered — one per scan of the surface. */
27
+ registrationCount: (name?: string) => number;
26
28
  restore: () => void;
27
29
  }
28
30
  export declare function installHighlightApi(): HighlightApiHarness;