@dbcdk/react-components 0.0.181 → 0.0.183

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 (56) hide show
  1. package/dist/client.cjs +21 -0
  2. package/dist/client.d.ts +3 -0
  3. package/dist/client.js +3 -0
  4. package/dist/components/clear-button/ClearButton.cjs +35 -12
  5. package/dist/components/clear-button/ClearButton.d.ts +17 -1
  6. package/dist/components/clear-button/ClearButton.js +35 -12
  7. package/dist/components/clear-button/ClearButton.module.css +12 -0
  8. package/dist/components/forms/multi-select/MultiSelect.cjs +2 -1
  9. package/dist/components/forms/multi-select/MultiSelect.js +2 -1
  10. package/dist/components/forms/select/Select.cjs +3 -1
  11. package/dist/components/forms/select/Select.js +3 -1
  12. package/dist/components/interval-select/IntervalSelect.cjs +2 -1
  13. package/dist/components/interval-select/IntervalSelect.js +2 -1
  14. package/dist/components/json-viewer/JsonViewer.cjs +3 -2
  15. package/dist/components/json-viewer/JsonViewer.d.ts +1 -1
  16. package/dist/components/json-viewer/JsonViewer.js +3 -2
  17. package/dist/components/json-viewer/JsonViewer.module.css +7 -0
  18. package/dist/components/json-viewer/types.d.ts +6 -0
  19. package/dist/components/line-viewer/LineViewer.cjs +174 -0
  20. package/dist/components/line-viewer/LineViewer.d.ts +20 -0
  21. package/dist/components/line-viewer/LineViewer.js +168 -0
  22. package/dist/components/line-viewer/LineViewer.module.css +112 -0
  23. package/dist/components/line-viewer/tokenizeLineFormat.cjs +52 -0
  24. package/dist/components/line-viewer/tokenizeLineFormat.d.ts +14 -0
  25. package/dist/components/line-viewer/tokenizeLineFormat.js +50 -0
  26. package/dist/components/tree-view/TreeNodeRow.cjs +99 -0
  27. package/dist/components/tree-view/TreeNodeRow.d.ts +18 -0
  28. package/dist/components/tree-view/TreeNodeRow.js +93 -0
  29. package/dist/components/tree-view/TreeView.cjs +93 -0
  30. package/dist/components/tree-view/TreeView.d.ts +20 -0
  31. package/dist/components/tree-view/TreeView.js +79 -0
  32. package/dist/components/tree-view/TreeView.module.css +141 -0
  33. package/dist/components/tree-view/types.cjs +2 -0
  34. package/dist/components/tree-view/types.d.ts +44 -0
  35. package/dist/components/tree-view/types.js +1 -0
  36. package/dist/components/tree-view/useTreeExpansion.cjs +47 -0
  37. package/dist/components/tree-view/useTreeExpansion.d.ts +17 -0
  38. package/dist/components/tree-view/useTreeExpansion.js +45 -0
  39. package/dist/components/tree-view/utils.cjs +32 -0
  40. package/dist/components/tree-view/utils.d.ts +16 -0
  41. package/dist/components/tree-view/utils.js +29 -0
  42. package/dist/components/xml-viewer/XmlViewer.cjs +175 -0
  43. package/dist/components/xml-viewer/XmlViewer.d.ts +20 -0
  44. package/dist/components/xml-viewer/XmlViewer.js +169 -0
  45. package/dist/components/xml-viewer/XmlViewer.module.css +109 -0
  46. package/dist/components/xml-viewer/tokenizeXml.cjs +50 -0
  47. package/dist/components/xml-viewer/tokenizeXml.d.ts +12 -0
  48. package/dist/components/xml-viewer/tokenizeXml.js +48 -0
  49. package/dist/index.cjs +7 -0
  50. package/dist/index.css +3 -0
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.js +1 -0
  53. package/dist/utils/date/formatDate.cjs +29 -17
  54. package/dist/utils/date/formatDate.d.ts +7 -0
  55. package/dist/utils/date/formatDate.js +29 -17
  56. package/package.json +1 -1
package/dist/client.cjs CHANGED
@@ -40,6 +40,7 @@ var severity_types = require('./constants/severity.types');
40
40
  var Textarea = require('./components/forms/text-area/Textarea');
41
41
  var AppHeader = require('./components/app-header/AppHeader');
42
42
  var Sidebar = require('./components/sidebar/Sidebar');
43
+ var TreeView = require('./components/tree-view/TreeView');
43
44
  var nestedFiltering = require('./utils/arrays/nested-filtering');
44
45
  var MultiSelect = require('./components/forms/multi-select/MultiSelect');
45
46
  var useViewportFill = require('./hooks/useViewportFill');
@@ -59,6 +60,8 @@ var Pagination = require('./components/pagination/Pagination');
59
60
  var MetaBar = require('./components/meta-bar/MetaBar');
60
61
  var CodeBlock = require('./components/code-block/CodeBlock');
61
62
  var JsonViewer = require('./components/json-viewer/JsonViewer');
63
+ var XmlViewer = require('./components/xml-viewer/XmlViewer');
64
+ var LineViewer = require('./components/line-viewer/LineViewer');
62
65
  var useTimeDuration = require('./hooks/useTimeDuration');
63
66
  var useSorting = require('./hooks/useSorting');
64
67
  var usePagination = require('./hooks/usePagination');
@@ -330,6 +333,12 @@ Object.keys(Sidebar).forEach(function (k) {
330
333
  get: function () { return Sidebar[k]; }
331
334
  });
332
335
  });
336
+ Object.keys(TreeView).forEach(function (k) {
337
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
338
+ enumerable: true,
339
+ get: function () { return TreeView[k]; }
340
+ });
341
+ });
333
342
  Object.keys(nestedFiltering).forEach(function (k) {
334
343
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
335
344
  enumerable: true,
@@ -444,6 +453,18 @@ Object.keys(JsonViewer).forEach(function (k) {
444
453
  get: function () { return JsonViewer[k]; }
445
454
  });
446
455
  });
456
+ Object.keys(XmlViewer).forEach(function (k) {
457
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
458
+ enumerable: true,
459
+ get: function () { return XmlViewer[k]; }
460
+ });
461
+ });
462
+ Object.keys(LineViewer).forEach(function (k) {
463
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
464
+ enumerable: true,
465
+ get: function () { return LineViewer[k]; }
466
+ });
467
+ });
447
468
  Object.keys(useTimeDuration).forEach(function (k) {
448
469
  if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
449
470
  enumerable: true,
package/dist/client.d.ts CHANGED
@@ -37,6 +37,7 @@ export * from './constants/severity.types';
37
37
  export * from './components/forms/text-area/Textarea';
38
38
  export * from './components/app-header/AppHeader';
39
39
  export * from './components/sidebar/Sidebar';
40
+ export * from './components/tree-view/TreeView';
40
41
  export * from './utils/arrays/nested-filtering';
41
42
  export * from './components/forms/multi-select/MultiSelect';
42
43
  export * from './hooks/useViewportFill';
@@ -56,6 +57,8 @@ export * from './components/pagination/Pagination';
56
57
  export * from './components/meta-bar/MetaBar';
57
58
  export * from './components/code-block/CodeBlock';
58
59
  export * from './components/json-viewer/JsonViewer';
60
+ export * from './components/xml-viewer/XmlViewer';
61
+ export * from './components/line-viewer/LineViewer';
59
62
  export * from './hooks/useTimeDuration';
60
63
  export * from './hooks/useSorting';
61
64
  export * from './hooks/usePagination';
package/dist/client.js CHANGED
@@ -38,6 +38,7 @@ export * from './constants/severity.types';
38
38
  export * from './components/forms/text-area/Textarea';
39
39
  export * from './components/app-header/AppHeader';
40
40
  export * from './components/sidebar/Sidebar';
41
+ export * from './components/tree-view/TreeView';
41
42
  export * from './utils/arrays/nested-filtering';
42
43
  export * from './components/forms/multi-select/MultiSelect';
43
44
  export * from './hooks/useViewportFill';
@@ -57,6 +58,8 @@ export * from './components/pagination/Pagination';
57
58
  export * from './components/meta-bar/MetaBar';
58
59
  export * from './components/code-block/CodeBlock';
59
60
  export * from './components/json-viewer/JsonViewer';
61
+ export * from './components/xml-viewer/XmlViewer';
62
+ export * from './components/line-viewer/LineViewer';
60
63
  export * from './hooks/useTimeDuration';
61
64
  export * from './hooks/useSorting';
62
65
  export * from './hooks/usePagination';
@@ -11,25 +11,48 @@ var styles__default = /*#__PURE__*/_interopDefault(styles);
11
11
  function ClearButton({
12
12
  onClick,
13
13
  ariaLabel = "Ryd",
14
- variant = "default"
14
+ variant = "default",
15
+ as = "button",
16
+ revealOnHover = false
15
17
  }) {
16
- const wrapperClassName = [styles__default.default.clearButton, variant === "header" ? styles__default.default.header : ""].filter(Boolean).join(" ");
17
- return /* @__PURE__ */ jsxRuntime.jsx("span", { className: wrapperClassName, children: /* @__PURE__ */ jsxRuntime.jsx(
18
+ const wrapperClassName = [
19
+ styles__default.default.clearButton,
20
+ variant === "header" ? styles__default.default.header : "",
21
+ revealOnHover ? styles__default.default.revealOnHover : ""
22
+ ].filter(Boolean).join(" ");
23
+ const handleMouseDown = (e) => {
24
+ e.preventDefault();
25
+ e.stopPropagation();
26
+ };
27
+ const handleClick = (e) => {
28
+ e.preventDefault();
29
+ e.stopPropagation();
30
+ onClick == null ? void 0 : onClick(e);
31
+ };
32
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: wrapperClassName, children: as === "span" ? /* @__PURE__ */ jsxRuntime.jsx(
33
+ "span",
34
+ {
35
+ className: styles__default.default.button,
36
+ role: "button",
37
+ tabIndex: 0,
38
+ "aria-label": ariaLabel,
39
+ "data-input-role": "clear",
40
+ onMouseDown: handleMouseDown,
41
+ onClick: handleClick,
42
+ onKeyDown: (e) => {
43
+ if (e.key === "Enter" || e.key === " ") handleClick(e);
44
+ },
45
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 16 })
46
+ }
47
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
18
48
  "button",
19
49
  {
20
50
  className: styles__default.default.button,
21
51
  type: "button",
22
52
  "aria-label": ariaLabel,
23
53
  "data-input-role": "clear",
24
- onMouseDown: (e) => {
25
- e.preventDefault();
26
- e.stopPropagation();
27
- },
28
- onClick: (e) => {
29
- e.preventDefault();
30
- e.stopPropagation();
31
- onClick == null ? void 0 : onClick(e);
32
- },
54
+ onMouseDown: handleMouseDown,
55
+ onClick: handleClick,
33
56
  children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { size: 16 })
34
57
  }
35
58
  ) });
@@ -5,6 +5,22 @@ interface ClearButtonProps {
5
5
  ariaLabel?: string;
6
6
  /** 'header' uses --color-navbar-fg tokens — only meaningful inside/near AppHeader */
7
7
  variant?: 'default' | 'header';
8
+ /**
9
+ * 'button' (default) renders a native <button>. Pass 'span' when this is
10
+ * nested inside another interactive <button> (e.g. a Select/MultiSelect/
11
+ * IntervalSelect trigger) - a <button> descendant of a <button> is invalid
12
+ * HTML and breaks hydration. The span variant keeps the same class,
13
+ * click/mousedown handling, and adds role="button" + Enter/Space
14
+ * activation so it stays keyboard-operable without the invalid nesting.
15
+ */
16
+ as?: 'button' | 'span';
17
+ /**
18
+ * When true, the button is hidden until the nearest ancestor <button>
19
+ * (e.g. a Select/MultiSelect/IntervalSelect trigger) is hovered or
20
+ * contains focus, instead of always being visible whenever there's a
21
+ * value to clear.
22
+ */
23
+ revealOnHover?: boolean;
8
24
  }
9
- export declare function ClearButton({ onClick, ariaLabel, variant, }: ClearButtonProps): ReactNode;
25
+ export declare function ClearButton({ onClick, ariaLabel, variant, as, revealOnHover, }: ClearButtonProps): ReactNode;
10
26
  export {};
@@ -5,25 +5,48 @@ import styles from './ClearButton.module.css';
5
5
  function ClearButton({
6
6
  onClick,
7
7
  ariaLabel = "Ryd",
8
- variant = "default"
8
+ variant = "default",
9
+ as = "button",
10
+ revealOnHover = false
9
11
  }) {
10
- const wrapperClassName = [styles.clearButton, variant === "header" ? styles.header : ""].filter(Boolean).join(" ");
11
- return /* @__PURE__ */ jsx("span", { className: wrapperClassName, children: /* @__PURE__ */ jsx(
12
+ const wrapperClassName = [
13
+ styles.clearButton,
14
+ variant === "header" ? styles.header : "",
15
+ revealOnHover ? styles.revealOnHover : ""
16
+ ].filter(Boolean).join(" ");
17
+ const handleMouseDown = (e) => {
18
+ e.preventDefault();
19
+ e.stopPropagation();
20
+ };
21
+ const handleClick = (e) => {
22
+ e.preventDefault();
23
+ e.stopPropagation();
24
+ onClick == null ? void 0 : onClick(e);
25
+ };
26
+ return /* @__PURE__ */ jsx("span", { className: wrapperClassName, children: as === "span" ? /* @__PURE__ */ jsx(
27
+ "span",
28
+ {
29
+ className: styles.button,
30
+ role: "button",
31
+ tabIndex: 0,
32
+ "aria-label": ariaLabel,
33
+ "data-input-role": "clear",
34
+ onMouseDown: handleMouseDown,
35
+ onClick: handleClick,
36
+ onKeyDown: (e) => {
37
+ if (e.key === "Enter" || e.key === " ") handleClick(e);
38
+ },
39
+ children: /* @__PURE__ */ jsx(X, { size: 16 })
40
+ }
41
+ ) : /* @__PURE__ */ jsx(
12
42
  "button",
13
43
  {
14
44
  className: styles.button,
15
45
  type: "button",
16
46
  "aria-label": ariaLabel,
17
47
  "data-input-role": "clear",
18
- onMouseDown: (e) => {
19
- e.preventDefault();
20
- e.stopPropagation();
21
- },
22
- onClick: (e) => {
23
- e.preventDefault();
24
- e.stopPropagation();
25
- onClick == null ? void 0 : onClick(e);
26
- },
48
+ onMouseDown: handleMouseDown,
49
+ onClick: handleClick,
27
50
  children: /* @__PURE__ */ jsx(X, { size: 16 })
28
51
  }
29
52
  ) });
@@ -33,3 +33,15 @@
33
33
  background-color: color-mix(in srgb, var(--color-navbar-fg) 12%, transparent);
34
34
  color: var(--color-navbar-fg);
35
35
  }
36
+
37
+ .clearButton.revealOnHover {
38
+ opacity: 0;
39
+ pointer-events: none;
40
+ transition: opacity var(--transition-fast) var(--ease-standard);
41
+ }
42
+
43
+ button:hover .clearButton.revealOnHover,
44
+ button:focus-within .clearButton.revealOnHover {
45
+ opacity: 1;
46
+ pointer-events: auto;
47
+ }
@@ -156,7 +156,8 @@ function MultiSelect({
156
156
  ClearButton.ClearButton,
157
157
  {
158
158
  onClick: onClear,
159
- variant: variant === "header" ? "header" : "default"
159
+ variant: variant === "header" ? "header" : "default",
160
+ as: "span"
160
161
  }
161
162
  ) : null,
162
163
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--color-fg-subtle)", display: "inline-flex" }, children: icon })
@@ -154,7 +154,8 @@ function MultiSelect({
154
154
  ClearButton,
155
155
  {
156
156
  onClick: onClear,
157
- variant: variant === "header" ? "header" : "default"
157
+ variant: variant === "header" ? "header" : "default",
158
+ as: "span"
158
159
  }
159
160
  ) : null,
160
161
  /* @__PURE__ */ jsx("span", { style: { color: "var(--color-fg-subtle)", display: "inline-flex" }, children: icon })
@@ -234,7 +234,9 @@ function Select({
234
234
  ClearButton.ClearButton,
235
235
  {
236
236
  onClick: onClear,
237
- variant: variant === "header" ? "header" : "default"
237
+ variant: variant === "header" ? "header" : "default",
238
+ as: "span",
239
+ revealOnHover: true
238
240
  }
239
241
  ),
240
242
  /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "var(--color-fg-subtle)", display: "inline-flex" }, children: icon })
@@ -228,7 +228,9 @@ function Select({
228
228
  ClearButton,
229
229
  {
230
230
  onClick: onClear,
231
- variant: variant === "header" ? "header" : "default"
231
+ variant: variant === "header" ? "header" : "default",
232
+ as: "span",
233
+ revealOnHover: true
232
234
  }
233
235
  ),
234
236
  /* @__PURE__ */ jsx("span", { style: { color: "var(--color-fg-subtle)", display: "inline-flex" }, children: icon })
@@ -158,7 +158,8 @@ function IntervalSelect({
158
158
  ClearButton.ClearButton,
159
159
  {
160
160
  onClick: onClear,
161
- variant: variant === "header" ? "header" : "default"
161
+ variant: variant === "header" ? "header" : "default",
162
+ as: "span"
162
163
  }
163
164
  ),
164
165
  icon
@@ -156,7 +156,8 @@ function IntervalSelect({
156
156
  ClearButton,
157
157
  {
158
158
  onClick: onClear,
159
- variant: variant === "header" ? "header" : "default"
159
+ variant: variant === "header" ? "header" : "default",
160
+ as: "span"
160
161
  }
161
162
  ),
162
163
  icon
@@ -29,7 +29,8 @@ function JsonViewer({
29
29
  className,
30
30
  maxHeight,
31
31
  appearance = "dark",
32
- storageKey
32
+ storageKey,
33
+ borderless = false
33
34
  }) {
34
35
  const [queryInput, setQueryInput] = react.useState("");
35
36
  const [query, setQuery] = react.useState("");
@@ -100,7 +101,7 @@ function JsonViewer({
100
101
  return /* @__PURE__ */ jsxRuntime.jsxs(
101
102
  "section",
102
103
  {
103
- className: [styles__default.default.viewer, className].filter(Boolean).join(" "),
104
+ className: [styles__default.default.viewer, borderless ? styles__default.default.borderless : "", className].filter(Boolean).join(" "),
104
105
  "data-appearance": currentAppearance,
105
106
  children: [
106
107
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -1,4 +1,4 @@
1
1
  import type { JSX } from 'react';
2
2
  import type { JsonViewerProps } from './types';
3
3
  export type { JsonViewerProps } from './types';
4
- export declare function JsonViewer({ value, defaultExpandedDepth, expandAll, searchDebounceMs, helperText, searchPlaceholder, emptySearchText, className, maxHeight, appearance, storageKey, }: JsonViewerProps): JSX.Element;
4
+ export declare function JsonViewer({ value, defaultExpandedDepth, expandAll, searchDebounceMs, helperText, searchPlaceholder, emptySearchText, className, maxHeight, appearance, storageKey, borderless, }: JsonViewerProps): JSX.Element;
@@ -23,7 +23,8 @@ function JsonViewer({
23
23
  className,
24
24
  maxHeight,
25
25
  appearance = "dark",
26
- storageKey
26
+ storageKey,
27
+ borderless = false
27
28
  }) {
28
29
  const [queryInput, setQueryInput] = useState("");
29
30
  const [query, setQuery] = useState("");
@@ -94,7 +95,7 @@ function JsonViewer({
94
95
  return /* @__PURE__ */ jsxs(
95
96
  "section",
96
97
  {
97
- className: [styles.viewer, className].filter(Boolean).join(" "),
98
+ className: [styles.viewer, borderless ? styles.borderless : "", className].filter(Boolean).join(" "),
98
99
  "data-appearance": currentAppearance,
99
100
  children: [
100
101
  /* @__PURE__ */ jsxs(
@@ -51,6 +51,13 @@
51
51
  box-shadow: none;
52
52
  }
53
53
 
54
+ .viewer.borderless {
55
+ border: none;
56
+ border-radius: 0;
57
+ box-shadow: none;
58
+ padding: 0;
59
+ }
60
+
54
61
  .toolbar {
55
62
  display: grid;
56
63
  gap: var(--spacing-xs);
@@ -25,6 +25,12 @@ export interface JsonViewerProps {
25
25
  * under `${storageKey}:appearance`.
26
26
  */
27
27
  storageKey?: string;
28
+ /**
29
+ * Removes the outer border, shadow, corner radius and padding, so the
30
+ * viewer sits flush in a container that already provides its own framing
31
+ * (e.g. a modal).
32
+ */
33
+ borderless?: boolean;
28
34
  }
29
35
  export type JsonNodeProps = {
30
36
  keyName?: string;
@@ -0,0 +1,174 @@
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 Menu = require('../../components/menu/Menu');
8
+ var Popover = require('../../components/popover/Popover');
9
+ var usePersistentState = require('../../hooks/usePersistentState');
10
+ var styles = require('./LineViewer.module.css');
11
+ var tokenizeLineFormat = require('./tokenizeLineFormat');
12
+ var Button = require('../button/Button');
13
+
14
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
+
16
+ var styles__default = /*#__PURE__*/_interopDefault(styles);
17
+
18
+ const TOKEN_CLASS = {
19
+ tag: styles__default.default.tag,
20
+ indicator: styles__default.default.indicator,
21
+ subfieldMarker: styles__default.default.subfieldMarker,
22
+ subfieldCode: styles__default.default.subfieldCode,
23
+ value: styles__default.default.value,
24
+ terminator: styles__default.default.terminator,
25
+ text: styles__default.default.text,
26
+ whitespace: void 0
27
+ };
28
+ function LineViewer({
29
+ lines,
30
+ size = "md",
31
+ appearance = "dark",
32
+ storageKey,
33
+ borderless = false
34
+ }) {
35
+ const tokens = react.useMemo(() => tokenizeLineFormat.tokenizeLineFormat(lines), [lines]);
36
+ const codeRef = react.useRef(null);
37
+ const { value: currentAppearance, setValue: setCurrentAppearance } = usePersistentState.usePersistentState({
38
+ initialValue: appearance,
39
+ storageKey: storageKey ? `${storageKey}:appearance` : void 0,
40
+ validate: (stored) => stored === "dark" || stored === "light"
41
+ });
42
+ const { value: viewMode, setValue: setViewMode } = usePersistentState.usePersistentState({
43
+ initialValue: "highlighted",
44
+ storageKey: storageKey ? `${storageKey}:viewMode` : void 0,
45
+ validate: (stored) => stored === "highlighted" || stored === "raw"
46
+ });
47
+ const { value: wrap, setValue: setWrap } = usePersistentState.usePersistentState({
48
+ initialValue: true,
49
+ storageKey: storageKey ? `${storageKey}:wrap` : void 0,
50
+ validate: (stored) => typeof stored === "boolean"
51
+ });
52
+ const handleCopy = () => {
53
+ var _a;
54
+ (_a = navigator.clipboard) == null ? void 0 : _a.writeText(lines).catch(() => {
55
+ });
56
+ };
57
+ const handleDoubleClick = () => {
58
+ const el = codeRef.current;
59
+ const selection = typeof window !== "undefined" ? window.getSelection() : null;
60
+ if (!el || !selection) return;
61
+ const range = document.createRange();
62
+ range.selectNodeContents(el);
63
+ selection.removeAllRanges();
64
+ selection.addRange(range);
65
+ };
66
+ return /* @__PURE__ */ jsxRuntime.jsxs(
67
+ "section",
68
+ {
69
+ className: [styles__default.default.viewer, borderless ? styles__default.default.borderless : ""].filter(Boolean).join(" "),
70
+ "data-appearance": currentAppearance,
71
+ children: [
72
+ /* @__PURE__ */ jsxRuntime.jsx(
73
+ "div",
74
+ {
75
+ className: styles__default.default.toolbar,
76
+ "data-surface": currentAppearance === "dark" ? "inverse" : void 0,
77
+ children: /* @__PURE__ */ jsxRuntime.jsx(
78
+ Popover.Popover,
79
+ {
80
+ matchTriggerWidth: false,
81
+ minWidth: "200px",
82
+ trigger: (toggle, _icon, isOpen) => /* @__PURE__ */ jsxRuntime.jsx(
83
+ Button.Button,
84
+ {
85
+ variant: "inline",
86
+ "aria-label": "Flere handlinger",
87
+ "aria-haspopup": "menu",
88
+ "aria-expanded": isOpen ? true : false,
89
+ onClick: toggle,
90
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreVertical, { "aria-hidden": "true" })
91
+ }
92
+ ),
93
+ children: (close) => /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu, { children: [
94
+ /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(
95
+ "button",
96
+ {
97
+ type: "button",
98
+ onClick: () => {
99
+ setWrap((value) => !value);
100
+ close();
101
+ },
102
+ children: [
103
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.TextWrap, { "aria-hidden": "true" }),
104
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: wrap ? "Ombryd ikke tekst" : "Ombryd tekst" })
105
+ ]
106
+ }
107
+ ) }),
108
+ /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
109
+ /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(
110
+ "button",
111
+ {
112
+ type: "button",
113
+ onClick: () => {
114
+ setViewMode((mode) => mode === "raw" ? "highlighted" : "raw");
115
+ close();
116
+ },
117
+ children: [
118
+ viewMode === "raw" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListTree, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code2, { "aria-hidden": "true" }),
119
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: viewMode === "raw" ? "Vis med farver" : "Vis raw" })
120
+ ]
121
+ }
122
+ ) }),
123
+ /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(
124
+ "button",
125
+ {
126
+ type: "button",
127
+ onClick: () => {
128
+ setCurrentAppearance((value) => value === "dark" ? "light" : "dark");
129
+ close();
130
+ },
131
+ children: [
132
+ currentAppearance === "dark" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sun, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Moon, { "aria-hidden": "true" }),
133
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: currentAppearance === "dark" ? "Lys visning" : "M\xF8rk visning" })
134
+ ]
135
+ }
136
+ ) }),
137
+ /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
138
+ /* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(
139
+ "button",
140
+ {
141
+ type: "button",
142
+ onClick: () => {
143
+ handleCopy();
144
+ close();
145
+ },
146
+ children: [
147
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClipboardCopy, { "aria-hidden": "true" }),
148
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Kopi\xE9r" })
149
+ ]
150
+ }
151
+ ) })
152
+ ] })
153
+ }
154
+ )
155
+ }
156
+ ),
157
+ /* @__PURE__ */ jsxRuntime.jsx(
158
+ "pre",
159
+ {
160
+ className: [styles__default.default.codePane, styles__default.default[size], wrap ? styles__default.default.wrap : styles__default.default.noWrap].join(" "),
161
+ tabIndex: 0,
162
+ onDoubleClick: handleDoubleClick,
163
+ children: /* @__PURE__ */ jsxRuntime.jsx("code", { ref: codeRef, children: viewMode === "raw" ? lines : tokens.map((token, index) => {
164
+ const tokenClassName = TOKEN_CLASS[token.type];
165
+ return tokenClassName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: tokenClassName, children: token.value }, index) : token.value;
166
+ }) })
167
+ }
168
+ )
169
+ ]
170
+ }
171
+ );
172
+ }
173
+
174
+ exports.LineViewer = LineViewer;
@@ -0,0 +1,20 @@
1
+ import type { JSX } from 'react';
2
+ export type LineViewerAppearance = 'dark' | 'light';
3
+ export interface LineViewerProps {
4
+ lines: string;
5
+ size?: 'xs' | 'sm' | 'md' | 'lg';
6
+ /** Initial appearance. The user can toggle it via the kebab menu; defaults to 'dark'. */
7
+ appearance?: LineViewerAppearance;
8
+ /**
9
+ * When set, the user's appearance/view-mode/wrap choices are persisted to
10
+ * localStorage under `${storageKey}:appearance` etc.
11
+ */
12
+ storageKey?: string;
13
+ /**
14
+ * Removes the outer border, shadow and corner radius, so the viewer sits
15
+ * flush in a container that already provides its own framing (e.g. a
16
+ * modal).
17
+ */
18
+ borderless?: boolean;
19
+ }
20
+ export declare function LineViewer({ lines, size, appearance, storageKey, borderless, }: LineViewerProps): JSX.Element;