@dbcdk/react-components 0.0.195 → 0.0.197

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 (109) hide show
  1. package/README.md +78 -10
  2. package/dist/client.cjs +486 -614
  3. package/dist/client.d.ts +176 -102
  4. package/dist/client.js +102 -102
  5. package/dist/components/color-scheme-button/ColorSchemeButton.cjs +7 -4
  6. package/dist/components/color-scheme-button/ColorSchemeButton.d.ts +7 -3
  7. package/dist/components/color-scheme-button/ColorSchemeButton.js +7 -4
  8. package/dist/components/forms/text-area/Textarea.cjs +2 -1
  9. package/dist/components/forms/text-area/Textarea.d.ts +1 -0
  10. package/dist/components/forms/text-area/Textarea.js +2 -1
  11. package/dist/components/highlighted-text/HighlightedText.cjs +6 -3
  12. package/dist/components/highlighted-text/HighlightedText.js +7 -4
  13. package/dist/components/json-viewer/JsonNode.cjs +27 -67
  14. package/dist/components/json-viewer/JsonNode.d.ts +10 -0
  15. package/dist/components/json-viewer/JsonNode.js +28 -68
  16. package/dist/components/json-viewer/JsonRow.cjs +85 -0
  17. package/dist/components/json-viewer/JsonRow.d.ts +5 -0
  18. package/dist/components/json-viewer/JsonRow.js +79 -0
  19. package/dist/components/json-viewer/JsonViewer.cjs +36 -253
  20. package/dist/components/json-viewer/JsonViewer.js +37 -250
  21. package/dist/components/json-viewer/JsonViewerShell.cjs +208 -0
  22. package/dist/components/json-viewer/JsonViewerShell.d.ts +25 -0
  23. package/dist/components/json-viewer/JsonViewerShell.js +202 -0
  24. package/dist/components/json-viewer/TanstackJsonViewer.cjs +127 -0
  25. package/dist/components/json-viewer/TanstackJsonViewer.d.ts +17 -0
  26. package/dist/components/json-viewer/TanstackJsonViewer.js +121 -0
  27. package/dist/components/json-viewer/types.d.ts +27 -0
  28. package/dist/components/json-viewer/useJsonViewerState.cjs +111 -0
  29. package/dist/components/json-viewer/useJsonViewerState.d.ts +42 -0
  30. package/dist/components/json-viewer/useJsonViewerState.js +108 -0
  31. package/dist/components/json-viewer/utils.cjs +36 -0
  32. package/dist/components/json-viewer/utils.d.ts +21 -1
  33. package/dist/components/json-viewer/utils.js +35 -1
  34. package/dist/components/lightbox/Lightbox.cjs +2 -2
  35. package/dist/components/lightbox/Lightbox.d.ts +1 -1
  36. package/dist/components/lightbox/Lightbox.js +1 -1
  37. package/dist/components/menu/Menu.cjs +3 -23
  38. package/dist/components/menu/Menu.js +3 -23
  39. package/dist/components/menu/Menu.module.css +4 -3
  40. package/dist/components/metric-tile/MetricTile.cjs +3 -2
  41. package/dist/components/metric-tile/MetricTile.js +2 -1
  42. package/dist/components/overlay/tooltip/Tooltip.cjs +7 -2
  43. package/dist/components/overlay/tooltip/Tooltip.d.ts +7 -1
  44. package/dist/components/overlay/tooltip/Tooltip.js +7 -2
  45. package/dist/components/overlay/tooltip/useTooltipTrigger.cjs +7 -1
  46. package/dist/components/overlay/tooltip/useTooltipTrigger.js +7 -1
  47. package/dist/components/page-layout/PageLayout.module.css +1 -1
  48. package/dist/components/table/Table.cjs +45 -16
  49. package/dist/components/table/Table.d.ts +1 -1
  50. package/dist/components/table/Table.js +47 -18
  51. package/dist/components/table/Table.module.css +135 -7
  52. package/dist/components/table/Table.types.d.ts +47 -1
  53. package/dist/components/table/TanstackTable.cjs +30 -2
  54. package/dist/components/table/TanstackTable.js +31 -3
  55. package/dist/components/table/components/TableBody.d.ts +1 -2
  56. package/dist/components/table/components/TableHeader.cjs +6 -4
  57. package/dist/components/table/components/TableHeader.d.ts +2 -1
  58. package/dist/components/table/components/TableHeader.js +6 -4
  59. package/dist/components/table/components/TableHeaderCell.cjs +5 -4
  60. package/dist/components/table/components/TableHeaderCell.d.ts +3 -1
  61. package/dist/components/table/components/TableHeaderCell.js +5 -4
  62. package/dist/components/table/components/TableRow.cjs +1 -1
  63. package/dist/components/table/components/TableRow.d.ts +1 -2
  64. package/dist/components/table/components/TableRow.js +1 -1
  65. package/dist/components/table/components/TableSkeletonBody.cjs +30 -0
  66. package/dist/components/table/components/TableSkeletonBody.d.ts +13 -0
  67. package/dist/components/table/components/TableSkeletonBody.js +24 -0
  68. package/dist/components/table/components/table-settings/TableHeaderSettings.cjs +28 -0
  69. package/dist/components/table/components/table-settings/TableHeaderSettings.d.ts +11 -0
  70. package/dist/components/table/components/table-settings/TableHeaderSettings.js +26 -0
  71. package/dist/components/table/components/table-settings/TableSettings.cjs +82 -32
  72. package/dist/components/table/components/table-settings/TableSettings.d.ts +14 -6
  73. package/dist/components/table/components/table-settings/TableSettings.js +84 -34
  74. package/dist/components/table/table.utils.cjs +2 -0
  75. package/dist/components/table/table.utils.d.ts +6 -0
  76. package/dist/components/table/table.utils.js +2 -1
  77. package/dist/components/table/tableSettings.utils.cjs +29 -0
  78. package/dist/components/table/tableSettings.utils.d.ts +9 -0
  79. package/dist/components/table/tableSettings.utils.js +24 -0
  80. package/dist/components/table/tanstackTable.utils.cjs +18 -0
  81. package/dist/components/table/tanstackTable.utils.js +19 -1
  82. package/dist/components/theme-button/ThemeButton.cjs +9 -4
  83. package/dist/components/theme-button/ThemeButton.d.ts +4 -2
  84. package/dist/components/theme-button/ThemeButton.js +9 -4
  85. package/dist/components/theme-script/ThemeScript.cjs +10 -4
  86. package/dist/components/theme-script/ThemeScript.d.ts +9 -1
  87. package/dist/components/theme-script/ThemeScript.js +10 -4
  88. package/dist/hooks/useColorScheme.cjs +19 -15
  89. package/dist/hooks/useColorScheme.d.ts +12 -1
  90. package/dist/hooks/useColorScheme.js +20 -16
  91. package/dist/hooks/useGetActiveTheme.cjs +4 -3
  92. package/dist/hooks/useGetActiveTheme.d.ts +7 -1
  93. package/dist/hooks/useGetActiveTheme.js +4 -3
  94. package/dist/hooks/useTableData.cjs +11 -7
  95. package/dist/hooks/useTableData.d.ts +8 -2
  96. package/dist/hooks/useTableData.js +11 -7
  97. package/dist/hooks/useTableSettings.cjs +25 -9
  98. package/dist/hooks/useTableSettings.d.ts +9 -6
  99. package/dist/hooks/useTableSettings.js +25 -9
  100. package/dist/hooks/useTheme.cjs +15 -15
  101. package/dist/hooks/useTheme.d.ts +8 -0
  102. package/dist/hooks/useTheme.js +15 -15
  103. package/dist/styles/styles.css +7 -3
  104. package/dist/styles/themes/dbc/colors.css +1 -1
  105. package/dist/styles.css +1 -476
  106. package/dist/tanstack-virtual.cjs +12 -0
  107. package/dist/tanstack-virtual.d.ts +1 -0
  108. package/dist/tanstack-virtual.js +1 -0
  109. package/package.json +13 -1
@@ -9,6 +9,7 @@ export type TextareaProps = Omit<React.TextareaHTMLAttributes<HTMLTextAreaElemen
9
9
  showCount?: boolean;
10
10
  tooltip?: React.ReactNode;
11
11
  tooltipPlacement?: 'top' | 'right' | 'bottom' | 'left';
12
+ tooltipOpenOnFocus?: boolean;
12
13
  showTooltip?: boolean;
13
14
  adjustHeight?: boolean;
14
15
  placeholder?: string;
@@ -13,6 +13,7 @@ const Textarea = function Textarea2({
13
13
  showCount,
14
14
  tooltip,
15
15
  tooltipPlacement = "right",
16
+ tooltipOpenOnFocus = true,
16
17
  showTooltip,
17
18
  placeholder,
18
19
  adjustHeight,
@@ -81,7 +82,7 @@ const Textarea = function Textarea2({
81
82
  placement: tooltipPlacement,
82
83
  offset: 8,
83
84
  delayOpenMs: 0,
84
- focusOpenMode: "any",
85
+ focusOpenMode: tooltipOpenOnFocus ? "any" : "focus-visible",
85
86
  closeOnPointerDown: false
86
87
  });
87
88
  return /* @__PURE__ */ jsx(
@@ -8,11 +8,14 @@ function escapeRegExp(value) {
8
8
  }
9
9
  function HighlightedText({ text, query, className }) {
10
10
  const trimmedQuery = query == null ? void 0 : query.trim();
11
- if (!trimmedQuery) {
11
+ const parts = react.useMemo(() => {
12
+ if (!trimmedQuery) return null;
13
+ const pattern = new RegExp(`(${escapeRegExp(trimmedQuery)})`, "gi");
14
+ return text.split(pattern);
15
+ }, [text, trimmedQuery]);
16
+ if (!parts) {
12
17
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: text });
13
18
  }
14
- const pattern = new RegExp(`(${escapeRegExp(trimmedQuery)})`, "gi");
15
- const parts = text.split(pattern);
16
19
  return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: parts.map(
17
20
  (part, index) => index % 2 === 1 ? /* @__PURE__ */ jsxRuntime.jsx("mark", { className: "dbc-highlight", children: part }, index) : /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: part }, index)
18
21
  ) });
@@ -1,16 +1,19 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { Fragment } from 'react';
2
+ import { useMemo, Fragment } from 'react';
3
3
 
4
4
  function escapeRegExp(value) {
5
5
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6
6
  }
7
7
  function HighlightedText({ text, query, className }) {
8
8
  const trimmedQuery = query == null ? void 0 : query.trim();
9
- if (!trimmedQuery) {
9
+ const parts = useMemo(() => {
10
+ if (!trimmedQuery) return null;
11
+ const pattern = new RegExp(`(${escapeRegExp(trimmedQuery)})`, "gi");
12
+ return text.split(pattern);
13
+ }, [text, trimmedQuery]);
14
+ if (!parts) {
10
15
  return /* @__PURE__ */ jsx("span", { className, children: text });
11
16
  }
12
- const pattern = new RegExp(`(${escapeRegExp(trimmedQuery)})`, "gi");
13
- const parts = text.split(pattern);
14
17
  return /* @__PURE__ */ jsx("span", { className, children: parts.map(
15
18
  (part, index) => index % 2 === 1 ? /* @__PURE__ */ jsx("mark", { className: "dbc-highlight", children: part }, index) : /* @__PURE__ */ jsx(Fragment, { children: part }, index)
16
19
  ) });
@@ -2,8 +2,8 @@
2
2
  'use strict';
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
- var lucideReact = require('lucide-react');
6
- var HighlightedText = require('../../components/highlighted-text/HighlightedText');
5
+ var react = require('react');
6
+ var JsonRow = require('./JsonRow');
7
7
  var styles = require('./JsonViewer.module.css');
8
8
  var utils = require('./utils');
9
9
 
@@ -25,81 +25,41 @@ function JsonNode({
25
25
  onCopy
26
26
  }) {
27
27
  const nodeId = utils.getNodeId(path);
28
- const nodeType = utils.getValueType(value);
29
28
  const match = matches.get(nodeId);
30
- const shouldRender = query ? Boolean(match) : true;
31
- const forceOpen = query ? Boolean(match == null ? void 0 : match.descendant) : false;
29
+ const { isContainer, shouldRender, isExpanded } = utils.resolveNodeVisibility(
30
+ nodeId,
31
+ value,
32
+ query,
33
+ match,
34
+ expandedNodeIds
35
+ );
36
+ const entries = react.useMemo(() => {
37
+ if (utils.isJsonArray(value)) return value.map((item, index) => [String(index), item]);
38
+ if (utils.isJsonObject(value)) return Object.entries(value);
39
+ return [];
40
+ }, [value]);
32
41
  if (!shouldRender) return null;
33
- if (nodeType !== "array" && nodeType !== "object") {
34
- const primitive = value;
35
- const valueLabel = utils.formatPrimitive(primitive);
36
- const rawValue = utils.getPrimitiveRawValue(primitive);
37
- const copied = copiedId === nodeId;
38
- return /* @__PURE__ */ jsxRuntime.jsxs(
39
- "div",
40
- {
41
- className: styles__default.default.node,
42
- style: { ["--json-indent"]: depth },
43
- children: [
44
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.row, "data-match": (match == null ? void 0 : match.self) || void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
45
- "button",
46
- {
47
- type: "button",
48
- className: styles__default.default.valueButton,
49
- onClick: () => onCopy(nodeId, rawValue),
50
- title: copied ? "Kopieret" : "Kopi\xE9r v\xE6rdi",
51
- children: [
52
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.rowLabel, children: [
53
- keyName !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.keyChunk, children: [
54
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.key, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: keyName, query }) }),
55
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.punctuation, children: ":" })
56
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.rootLabel, children: "$" }),
57
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: [styles__default.default.value, styles__default.default[`value${utils.capitalize(nodeType)}`]].join(" "), children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: valueLabel, query }) })
58
- ] }),
59
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.copyState, "aria-live": "polite", children: [
60
- copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { "aria-hidden": "true" }),
61
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: copied ? "Kopieret" : "Kopi\xE9r" })
62
- ] })
63
- ]
64
- }
65
- ) }),
66
- query && !(match == null ? void 0 : match.self) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.pathHint, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: utils.getPathLabel(path), query }) }) : null
67
- ]
68
- }
69
- );
70
- }
71
- const entries = utils.isJsonArray(value) ? value.map((item, index) => [String(index), item]) : utils.isJsonObject(value) ? Object.entries(value) : [];
72
- const summary = utils.getSummary(value);
73
- const expanded = query || forceOpen ? true : expandedNodeIds.has(nodeId);
74
42
  return /* @__PURE__ */ jsxRuntime.jsxs(
75
43
  "div",
76
44
  {
77
45
  className: styles__default.default.node,
78
46
  style: { ["--json-indent"]: depth },
79
47
  children: [
80
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.row, "data-match": (match == null ? void 0 : match.self) || void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
81
- "button",
48
+ /* @__PURE__ */ jsxRuntime.jsx(
49
+ JsonRow.JsonRow,
82
50
  {
83
- type: "button",
84
- className: styles__default.default.toggle,
85
- onClick: () => onToggleNode(nodeId),
86
- "aria-expanded": expanded,
87
- children: [
88
- expanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true" }),
89
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.rowLabel, children: [
90
- keyName !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.keyChunk, children: [
91
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.key, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: keyName, query }) }),
92
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.punctuation, children: ":" })
93
- ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.rootLabel, children: "$" }),
94
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.bracket, children: utils.isJsonArray(value) ? "[" : "{" }),
95
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.summary, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: summary, query }) }),
96
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.bracket, children: utils.isJsonArray(value) ? "]" : "}" })
97
- ] })
98
- ]
51
+ nodeId,
52
+ keyName,
53
+ value,
54
+ query,
55
+ match,
56
+ isExpanded,
57
+ copied: copiedId === nodeId,
58
+ onToggleNode,
59
+ onCopy
99
60
  }
100
- ) }),
101
- query && !(match == null ? void 0 : match.self) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.pathHint, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: utils.getPathLabel(path), query }) }) : null,
102
- expanded ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.children, role: depth === 0 ? "group" : void 0, children: entries.map(([childKey, childValue]) => /* @__PURE__ */ jsxRuntime.jsx(
61
+ ),
62
+ isContainer && isExpanded ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.children, role: depth === 0 ? "group" : void 0, children: entries.map(([childKey, childValue]) => /* @__PURE__ */ jsxRuntime.jsx(
103
63
  JsonNode,
104
64
  {
105
65
  keyName: utils.isJsonArray(value) ? `[${childKey}]` : childKey,
@@ -1,3 +1,13 @@
1
1
  import type { JSX } from 'react';
2
2
  import type { JsonNodeProps } from './types';
3
+ /**
4
+ * Recursive tree orchestrator: resolves this node's own expanded/match state
5
+ * from the shared `expandedNodeIds`/`matches`, renders it via the memoized
6
+ * `JsonRow`, and recurses into children when expanded. Deliberately left
7
+ * unmemoized - it's cheap (a handful of derived values plus delegating to
8
+ * JsonRow), and it must always re-run so a toggle/search/copy anywhere in the
9
+ * tree keeps propagating the current shared state down to every descendant.
10
+ * The actual re-render savings come from JsonRow's memoization, not from
11
+ * skipping this function.
12
+ */
3
13
  export declare function JsonNode({ keyName, path, value, depth, defaultExpandedDepth, query, matches, expandedNodeIds, onToggleNode, copiedId, onCopy, }: JsonNodeProps): JSX.Element | null;
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { Check, Copy, ChevronDown, ChevronRight } from 'lucide-react';
4
- import { HighlightedText } from '../../components/highlighted-text/HighlightedText';
3
+ import { useMemo } from 'react';
4
+ import { JsonRow } from './JsonRow';
5
5
  import styles from './JsonViewer.module.css';
6
- import { getNodeId, getValueType, formatPrimitive, getPrimitiveRawValue, capitalize, getPathLabel, isJsonArray, isJsonObject, getSummary } from './utils';
6
+ import { getNodeId, resolveNodeVisibility, isJsonArray, isJsonObject } from './utils';
7
7
 
8
8
  function JsonNode({
9
9
  keyName,
@@ -19,81 +19,41 @@ function JsonNode({
19
19
  onCopy
20
20
  }) {
21
21
  const nodeId = getNodeId(path);
22
- const nodeType = getValueType(value);
23
22
  const match = matches.get(nodeId);
24
- const shouldRender = query ? Boolean(match) : true;
25
- const forceOpen = query ? Boolean(match == null ? void 0 : match.descendant) : false;
23
+ const { isContainer, shouldRender, isExpanded } = resolveNodeVisibility(
24
+ nodeId,
25
+ value,
26
+ query,
27
+ match,
28
+ expandedNodeIds
29
+ );
30
+ const entries = useMemo(() => {
31
+ if (isJsonArray(value)) return value.map((item, index) => [String(index), item]);
32
+ if (isJsonObject(value)) return Object.entries(value);
33
+ return [];
34
+ }, [value]);
26
35
  if (!shouldRender) return null;
27
- if (nodeType !== "array" && nodeType !== "object") {
28
- const primitive = value;
29
- const valueLabel = formatPrimitive(primitive);
30
- const rawValue = getPrimitiveRawValue(primitive);
31
- const copied = copiedId === nodeId;
32
- return /* @__PURE__ */ jsxs(
33
- "div",
34
- {
35
- className: styles.node,
36
- style: { ["--json-indent"]: depth },
37
- children: [
38
- /* @__PURE__ */ jsx("div", { className: styles.row, "data-match": (match == null ? void 0 : match.self) || void 0, children: /* @__PURE__ */ jsxs(
39
- "button",
40
- {
41
- type: "button",
42
- className: styles.valueButton,
43
- onClick: () => onCopy(nodeId, rawValue),
44
- title: copied ? "Kopieret" : "Kopi\xE9r v\xE6rdi",
45
- children: [
46
- /* @__PURE__ */ jsxs("span", { className: styles.rowLabel, children: [
47
- keyName !== void 0 ? /* @__PURE__ */ jsxs("span", { className: styles.keyChunk, children: [
48
- /* @__PURE__ */ jsx("span", { className: styles.key, children: /* @__PURE__ */ jsx(HighlightedText, { text: keyName, query }) }),
49
- /* @__PURE__ */ jsx("span", { className: styles.punctuation, children: ":" })
50
- ] }) : /* @__PURE__ */ jsx("span", { className: styles.rootLabel, children: "$" }),
51
- /* @__PURE__ */ jsx("span", { className: [styles.value, styles[`value${capitalize(nodeType)}`]].join(" "), children: /* @__PURE__ */ jsx(HighlightedText, { text: valueLabel, query }) })
52
- ] }),
53
- /* @__PURE__ */ jsxs("span", { className: styles.copyState, "aria-live": "polite", children: [
54
- copied ? /* @__PURE__ */ jsx(Check, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Copy, { "aria-hidden": "true" }),
55
- /* @__PURE__ */ jsx("span", { children: copied ? "Kopieret" : "Kopi\xE9r" })
56
- ] })
57
- ]
58
- }
59
- ) }),
60
- query && !(match == null ? void 0 : match.self) ? /* @__PURE__ */ jsx("div", { className: styles.pathHint, children: /* @__PURE__ */ jsx(HighlightedText, { text: getPathLabel(path), query }) }) : null
61
- ]
62
- }
63
- );
64
- }
65
- const entries = isJsonArray(value) ? value.map((item, index) => [String(index), item]) : isJsonObject(value) ? Object.entries(value) : [];
66
- const summary = getSummary(value);
67
- const expanded = query || forceOpen ? true : expandedNodeIds.has(nodeId);
68
36
  return /* @__PURE__ */ jsxs(
69
37
  "div",
70
38
  {
71
39
  className: styles.node,
72
40
  style: { ["--json-indent"]: depth },
73
41
  children: [
74
- /* @__PURE__ */ jsx("div", { className: styles.row, "data-match": (match == null ? void 0 : match.self) || void 0, children: /* @__PURE__ */ jsxs(
75
- "button",
42
+ /* @__PURE__ */ jsx(
43
+ JsonRow,
76
44
  {
77
- type: "button",
78
- className: styles.toggle,
79
- onClick: () => onToggleNode(nodeId),
80
- "aria-expanded": expanded,
81
- children: [
82
- expanded ? /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" }),
83
- /* @__PURE__ */ jsxs("span", { className: styles.rowLabel, children: [
84
- keyName !== void 0 ? /* @__PURE__ */ jsxs("span", { className: styles.keyChunk, children: [
85
- /* @__PURE__ */ jsx("span", { className: styles.key, children: /* @__PURE__ */ jsx(HighlightedText, { text: keyName, query }) }),
86
- /* @__PURE__ */ jsx("span", { className: styles.punctuation, children: ":" })
87
- ] }) : /* @__PURE__ */ jsx("span", { className: styles.rootLabel, children: "$" }),
88
- /* @__PURE__ */ jsx("span", { className: styles.bracket, children: isJsonArray(value) ? "[" : "{" }),
89
- /* @__PURE__ */ jsx("span", { className: styles.summary, children: /* @__PURE__ */ jsx(HighlightedText, { text: summary, query }) }),
90
- /* @__PURE__ */ jsx("span", { className: styles.bracket, children: isJsonArray(value) ? "]" : "}" })
91
- ] })
92
- ]
45
+ nodeId,
46
+ keyName,
47
+ value,
48
+ query,
49
+ match,
50
+ isExpanded,
51
+ copied: copiedId === nodeId,
52
+ onToggleNode,
53
+ onCopy
93
54
  }
94
- ) }),
95
- query && !(match == null ? void 0 : match.self) ? /* @__PURE__ */ jsx("div", { className: styles.pathHint, children: /* @__PURE__ */ jsx(HighlightedText, { text: getPathLabel(path), query }) }) : null,
96
- expanded ? /* @__PURE__ */ jsx("div", { className: styles.children, role: depth === 0 ? "group" : void 0, children: entries.map(([childKey, childValue]) => /* @__PURE__ */ jsx(
55
+ ),
56
+ isContainer && isExpanded ? /* @__PURE__ */ jsx("div", { className: styles.children, role: depth === 0 ? "group" : void 0, children: entries.map(([childKey, childValue]) => /* @__PURE__ */ jsx(
97
57
  JsonNode,
98
58
  {
99
59
  keyName: isJsonArray(value) ? `[${childKey}]` : childKey,
@@ -0,0 +1,85 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var lucideReact = require('lucide-react');
6
+ var react = require('react');
7
+ var HighlightedText = require('../../components/highlighted-text/HighlightedText');
8
+ var styles = require('./JsonViewer.module.css');
9
+ var utils = require('./utils');
10
+
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var styles__default = /*#__PURE__*/_interopDefault(styles);
14
+
15
+ function JsonRowComponent({
16
+ nodeId,
17
+ keyName,
18
+ value,
19
+ query,
20
+ match,
21
+ isExpanded,
22
+ copied,
23
+ onToggleNode,
24
+ onCopy
25
+ }) {
26
+ const nodeType = utils.getValueType(value);
27
+ if (nodeType !== "array" && nodeType !== "object") {
28
+ const primitive = value;
29
+ const valueLabel = utils.formatPrimitive(primitive);
30
+ const rawValue = utils.getPrimitiveRawValue(primitive);
31
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
32
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.row, "data-match": (match == null ? void 0 : match.self) || void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
33
+ "button",
34
+ {
35
+ type: "button",
36
+ className: styles__default.default.valueButton,
37
+ onClick: () => onCopy(nodeId, rawValue),
38
+ title: copied ? "Kopieret" : "Kopi\xE9r v\xE6rdi",
39
+ children: [
40
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.rowLabel, children: [
41
+ keyName !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.keyChunk, children: [
42
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.key, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: keyName, query }) }),
43
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.punctuation, children: ":" })
44
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.rootLabel, children: "$" }),
45
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: [styles__default.default.value, styles__default.default[`value${utils.capitalize(nodeType)}`]].join(" "), children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: valueLabel, query }) })
46
+ ] }),
47
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.copyState, "aria-live": "polite", children: [
48
+ copied ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, { "aria-hidden": "true" }),
49
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: copied ? "Kopieret" : "Kopi\xE9r" })
50
+ ] })
51
+ ]
52
+ }
53
+ ) }),
54
+ query && !(match == null ? void 0 : match.self) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.pathHint, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: nodeId, query }) }) : null
55
+ ] });
56
+ }
57
+ const summary = utils.getSummary(value);
58
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
59
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.row, "data-match": (match == null ? void 0 : match.self) || void 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
60
+ "button",
61
+ {
62
+ type: "button",
63
+ className: styles__default.default.toggle,
64
+ onClick: () => onToggleNode(nodeId),
65
+ "aria-expanded": isExpanded,
66
+ children: [
67
+ isExpanded ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { "aria-hidden": "true" }),
68
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.rowLabel, children: [
69
+ keyName !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: styles__default.default.keyChunk, children: [
70
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.key, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: keyName, query }) }),
71
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.punctuation, children: ":" })
72
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.rootLabel, children: "$" }),
73
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.bracket, children: utils.isJsonArray(value) ? "[" : "{" }),
74
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.summary, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: summary, query }) }),
75
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: styles__default.default.bracket, children: utils.isJsonArray(value) ? "]" : "}" })
76
+ ] })
77
+ ]
78
+ }
79
+ ) }),
80
+ query && !(match == null ? void 0 : match.self) ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: styles__default.default.pathHint, children: /* @__PURE__ */ jsxRuntime.jsx(HighlightedText.HighlightedText, { text: nodeId, query }) }) : null
81
+ ] });
82
+ }
83
+ const JsonRow = react.memo(JsonRowComponent);
84
+
85
+ exports.JsonRow = JsonRow;
@@ -0,0 +1,5 @@
1
+ import type { JSX } from 'react';
2
+ import type { JsonRowProps } from './types';
3
+ declare function JsonRowComponent({ nodeId, keyName, value, query, match, isExpanded, copied, onToggleNode, onCopy, }: JsonRowProps): JSX.Element;
4
+ export declare const JsonRow: import("react").MemoExoticComponent<typeof JsonRowComponent>;
5
+ export {};
@@ -0,0 +1,79 @@
1
+ 'use client';
2
+ import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
3
+ import { Check, Copy, ChevronDown, ChevronRight } from 'lucide-react';
4
+ import { memo } from 'react';
5
+ import { HighlightedText } from '../../components/highlighted-text/HighlightedText';
6
+ import styles from './JsonViewer.module.css';
7
+ import { getValueType, formatPrimitive, getPrimitiveRawValue, capitalize, getSummary, isJsonArray } from './utils';
8
+
9
+ function JsonRowComponent({
10
+ nodeId,
11
+ keyName,
12
+ value,
13
+ query,
14
+ match,
15
+ isExpanded,
16
+ copied,
17
+ onToggleNode,
18
+ onCopy
19
+ }) {
20
+ const nodeType = getValueType(value);
21
+ if (nodeType !== "array" && nodeType !== "object") {
22
+ const primitive = value;
23
+ const valueLabel = formatPrimitive(primitive);
24
+ const rawValue = getPrimitiveRawValue(primitive);
25
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
26
+ /* @__PURE__ */ jsx("div", { className: styles.row, "data-match": (match == null ? void 0 : match.self) || void 0, children: /* @__PURE__ */ jsxs(
27
+ "button",
28
+ {
29
+ type: "button",
30
+ className: styles.valueButton,
31
+ onClick: () => onCopy(nodeId, rawValue),
32
+ title: copied ? "Kopieret" : "Kopi\xE9r v\xE6rdi",
33
+ children: [
34
+ /* @__PURE__ */ jsxs("span", { className: styles.rowLabel, children: [
35
+ keyName !== void 0 ? /* @__PURE__ */ jsxs("span", { className: styles.keyChunk, children: [
36
+ /* @__PURE__ */ jsx("span", { className: styles.key, children: /* @__PURE__ */ jsx(HighlightedText, { text: keyName, query }) }),
37
+ /* @__PURE__ */ jsx("span", { className: styles.punctuation, children: ":" })
38
+ ] }) : /* @__PURE__ */ jsx("span", { className: styles.rootLabel, children: "$" }),
39
+ /* @__PURE__ */ jsx("span", { className: [styles.value, styles[`value${capitalize(nodeType)}`]].join(" "), children: /* @__PURE__ */ jsx(HighlightedText, { text: valueLabel, query }) })
40
+ ] }),
41
+ /* @__PURE__ */ jsxs("span", { className: styles.copyState, "aria-live": "polite", children: [
42
+ copied ? /* @__PURE__ */ jsx(Check, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Copy, { "aria-hidden": "true" }),
43
+ /* @__PURE__ */ jsx("span", { children: copied ? "Kopieret" : "Kopi\xE9r" })
44
+ ] })
45
+ ]
46
+ }
47
+ ) }),
48
+ query && !(match == null ? void 0 : match.self) ? /* @__PURE__ */ jsx("div", { className: styles.pathHint, children: /* @__PURE__ */ jsx(HighlightedText, { text: nodeId, query }) }) : null
49
+ ] });
50
+ }
51
+ const summary = getSummary(value);
52
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
53
+ /* @__PURE__ */ jsx("div", { className: styles.row, "data-match": (match == null ? void 0 : match.self) || void 0, children: /* @__PURE__ */ jsxs(
54
+ "button",
55
+ {
56
+ type: "button",
57
+ className: styles.toggle,
58
+ onClick: () => onToggleNode(nodeId),
59
+ "aria-expanded": isExpanded,
60
+ children: [
61
+ isExpanded ? /* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(ChevronRight, { "aria-hidden": "true" }),
62
+ /* @__PURE__ */ jsxs("span", { className: styles.rowLabel, children: [
63
+ keyName !== void 0 ? /* @__PURE__ */ jsxs("span", { className: styles.keyChunk, children: [
64
+ /* @__PURE__ */ jsx("span", { className: styles.key, children: /* @__PURE__ */ jsx(HighlightedText, { text: keyName, query }) }),
65
+ /* @__PURE__ */ jsx("span", { className: styles.punctuation, children: ":" })
66
+ ] }) : /* @__PURE__ */ jsx("span", { className: styles.rootLabel, children: "$" }),
67
+ /* @__PURE__ */ jsx("span", { className: styles.bracket, children: isJsonArray(value) ? "[" : "{" }),
68
+ /* @__PURE__ */ jsx("span", { className: styles.summary, children: /* @__PURE__ */ jsx(HighlightedText, { text: summary, query }) }),
69
+ /* @__PURE__ */ jsx("span", { className: styles.bracket, children: isJsonArray(value) ? "]" : "}" })
70
+ ] })
71
+ ]
72
+ }
73
+ ) }),
74
+ query && !(match == null ? void 0 : match.self) ? /* @__PURE__ */ jsx("div", { className: styles.pathHint, children: /* @__PURE__ */ jsx(HighlightedText, { text: nodeId, query }) }) : null
75
+ ] });
76
+ }
77
+ const JsonRow = memo(JsonRowComponent);
78
+
79
+ export { JsonRow };