@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.
- package/dist/client.cjs +21 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.js +3 -0
- package/dist/components/clear-button/ClearButton.cjs +35 -12
- package/dist/components/clear-button/ClearButton.d.ts +17 -1
- package/dist/components/clear-button/ClearButton.js +35 -12
- package/dist/components/clear-button/ClearButton.module.css +12 -0
- package/dist/components/forms/multi-select/MultiSelect.cjs +2 -1
- package/dist/components/forms/multi-select/MultiSelect.js +2 -1
- package/dist/components/forms/select/Select.cjs +3 -1
- package/dist/components/forms/select/Select.js +3 -1
- package/dist/components/interval-select/IntervalSelect.cjs +2 -1
- package/dist/components/interval-select/IntervalSelect.js +2 -1
- package/dist/components/json-viewer/JsonViewer.cjs +3 -2
- package/dist/components/json-viewer/JsonViewer.d.ts +1 -1
- package/dist/components/json-viewer/JsonViewer.js +3 -2
- package/dist/components/json-viewer/JsonViewer.module.css +7 -0
- package/dist/components/json-viewer/types.d.ts +6 -0
- package/dist/components/line-viewer/LineViewer.cjs +174 -0
- package/dist/components/line-viewer/LineViewer.d.ts +20 -0
- package/dist/components/line-viewer/LineViewer.js +168 -0
- package/dist/components/line-viewer/LineViewer.module.css +112 -0
- package/dist/components/line-viewer/tokenizeLineFormat.cjs +52 -0
- package/dist/components/line-viewer/tokenizeLineFormat.d.ts +14 -0
- package/dist/components/line-viewer/tokenizeLineFormat.js +50 -0
- package/dist/components/tree-view/TreeNodeRow.cjs +99 -0
- package/dist/components/tree-view/TreeNodeRow.d.ts +18 -0
- package/dist/components/tree-view/TreeNodeRow.js +93 -0
- package/dist/components/tree-view/TreeView.cjs +93 -0
- package/dist/components/tree-view/TreeView.d.ts +20 -0
- package/dist/components/tree-view/TreeView.js +79 -0
- package/dist/components/tree-view/TreeView.module.css +141 -0
- package/dist/components/tree-view/types.cjs +2 -0
- package/dist/components/tree-view/types.d.ts +44 -0
- package/dist/components/tree-view/types.js +1 -0
- package/dist/components/tree-view/useTreeExpansion.cjs +47 -0
- package/dist/components/tree-view/useTreeExpansion.d.ts +17 -0
- package/dist/components/tree-view/useTreeExpansion.js +45 -0
- package/dist/components/tree-view/utils.cjs +32 -0
- package/dist/components/tree-view/utils.d.ts +16 -0
- package/dist/components/tree-view/utils.js +29 -0
- package/dist/components/xml-viewer/XmlViewer.cjs +175 -0
- package/dist/components/xml-viewer/XmlViewer.d.ts +20 -0
- package/dist/components/xml-viewer/XmlViewer.js +169 -0
- package/dist/components/xml-viewer/XmlViewer.module.css +109 -0
- package/dist/components/xml-viewer/tokenizeXml.cjs +50 -0
- package/dist/components/xml-viewer/tokenizeXml.d.ts +12 -0
- package/dist/components/xml-viewer/tokenizeXml.js +48 -0
- package/dist/index.cjs +7 -0
- package/dist/index.css +3 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/utils/date/formatDate.cjs +29 -17
- package/dist/utils/date/formatDate.d.ts +7 -0
- package/dist/utils/date/formatDate.js +29 -17
- package/package.json +1 -1
|
@@ -0,0 +1,175 @@
|
|
|
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 tokenizeXml = require('./tokenizeXml');
|
|
11
|
+
var styles = require('./XmlViewer.module.css');
|
|
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
|
+
tagName: styles__default.default.tagName,
|
|
20
|
+
attrName: styles__default.default.attrName,
|
|
21
|
+
attrValue: styles__default.default.attrValue,
|
|
22
|
+
comment: styles__default.default.comment,
|
|
23
|
+
cdata: styles__default.default.cdata,
|
|
24
|
+
declaration: styles__default.default.declaration,
|
|
25
|
+
doctype: styles__default.default.doctype,
|
|
26
|
+
punctuation: styles__default.default.punctuation,
|
|
27
|
+
text: void 0
|
|
28
|
+
};
|
|
29
|
+
function XmlViewer({
|
|
30
|
+
xml,
|
|
31
|
+
size = "md",
|
|
32
|
+
appearance = "dark",
|
|
33
|
+
storageKey,
|
|
34
|
+
borderless = false
|
|
35
|
+
}) {
|
|
36
|
+
const tokens = react.useMemo(() => tokenizeXml.tokenizeXml(xml), [xml]);
|
|
37
|
+
const codeRef = react.useRef(null);
|
|
38
|
+
const { value: currentAppearance, setValue: setCurrentAppearance } = usePersistentState.usePersistentState({
|
|
39
|
+
initialValue: appearance,
|
|
40
|
+
storageKey: storageKey ? `${storageKey}:appearance` : void 0,
|
|
41
|
+
validate: (stored) => stored === "dark" || stored === "light"
|
|
42
|
+
});
|
|
43
|
+
const { value: viewMode, setValue: setViewMode } = usePersistentState.usePersistentState({
|
|
44
|
+
initialValue: "highlighted",
|
|
45
|
+
storageKey: storageKey ? `${storageKey}:viewMode` : void 0,
|
|
46
|
+
validate: (stored) => stored === "highlighted" || stored === "raw"
|
|
47
|
+
});
|
|
48
|
+
const { value: wrap, setValue: setWrap } = usePersistentState.usePersistentState({
|
|
49
|
+
initialValue: true,
|
|
50
|
+
storageKey: storageKey ? `${storageKey}:wrap` : void 0,
|
|
51
|
+
validate: (stored) => typeof stored === "boolean"
|
|
52
|
+
});
|
|
53
|
+
const handleCopy = () => {
|
|
54
|
+
var _a;
|
|
55
|
+
(_a = navigator.clipboard) == null ? void 0 : _a.writeText(xml).catch(() => {
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
const handleDoubleClick = () => {
|
|
59
|
+
const el = codeRef.current;
|
|
60
|
+
const selection = typeof window !== "undefined" ? window.getSelection() : null;
|
|
61
|
+
if (!el || !selection) return;
|
|
62
|
+
const range = document.createRange();
|
|
63
|
+
range.selectNodeContents(el);
|
|
64
|
+
selection.removeAllRanges();
|
|
65
|
+
selection.addRange(range);
|
|
66
|
+
};
|
|
67
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
68
|
+
"section",
|
|
69
|
+
{
|
|
70
|
+
className: [styles__default.default.viewer, borderless ? styles__default.default.borderless : ""].filter(Boolean).join(" "),
|
|
71
|
+
"data-appearance": currentAppearance,
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
74
|
+
"div",
|
|
75
|
+
{
|
|
76
|
+
className: styles__default.default.toolbar,
|
|
77
|
+
"data-surface": currentAppearance === "dark" ? "inverse" : void 0,
|
|
78
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
79
|
+
Popover.Popover,
|
|
80
|
+
{
|
|
81
|
+
matchTriggerWidth: false,
|
|
82
|
+
minWidth: "200px",
|
|
83
|
+
trigger: (toggle, _icon, isOpen) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
84
|
+
Button.Button,
|
|
85
|
+
{
|
|
86
|
+
variant: "inline",
|
|
87
|
+
"aria-label": "Flere handlinger",
|
|
88
|
+
"aria-haspopup": "menu",
|
|
89
|
+
"aria-expanded": isOpen ? true : false,
|
|
90
|
+
onClick: toggle,
|
|
91
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.MoreVertical, { "aria-hidden": "true" })
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
children: (close) => /* @__PURE__ */ jsxRuntime.jsxs(Menu.Menu, { children: [
|
|
95
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
96
|
+
"button",
|
|
97
|
+
{
|
|
98
|
+
type: "button",
|
|
99
|
+
onClick: () => {
|
|
100
|
+
setWrap((value) => !value);
|
|
101
|
+
close();
|
|
102
|
+
},
|
|
103
|
+
children: [
|
|
104
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.TextWrap, { "aria-hidden": "true" }),
|
|
105
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: wrap ? "Ombryd ikke tekst" : "Ombryd tekst" })
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
) }),
|
|
109
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
|
|
110
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
111
|
+
"button",
|
|
112
|
+
{
|
|
113
|
+
type: "button",
|
|
114
|
+
onClick: () => {
|
|
115
|
+
setViewMode((mode) => mode === "raw" ? "highlighted" : "raw");
|
|
116
|
+
close();
|
|
117
|
+
},
|
|
118
|
+
children: [
|
|
119
|
+
viewMode === "raw" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListTree, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Code2, { "aria-hidden": "true" }),
|
|
120
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: viewMode === "raw" ? "Vis med farver" : "Vis raw" })
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
) }),
|
|
124
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
125
|
+
"button",
|
|
126
|
+
{
|
|
127
|
+
type: "button",
|
|
128
|
+
onClick: () => {
|
|
129
|
+
setCurrentAppearance((value) => value === "dark" ? "light" : "dark");
|
|
130
|
+
close();
|
|
131
|
+
},
|
|
132
|
+
children: [
|
|
133
|
+
currentAppearance === "dark" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sun, { "aria-hidden": "true" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Moon, { "aria-hidden": "true" }),
|
|
134
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: currentAppearance === "dark" ? "Lys visning" : "M\xF8rk visning" })
|
|
135
|
+
]
|
|
136
|
+
}
|
|
137
|
+
) }),
|
|
138
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Separator, {}),
|
|
139
|
+
/* @__PURE__ */ jsxRuntime.jsx(Menu.Menu.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
140
|
+
"button",
|
|
141
|
+
{
|
|
142
|
+
type: "button",
|
|
143
|
+
onClick: () => {
|
|
144
|
+
handleCopy();
|
|
145
|
+
close();
|
|
146
|
+
},
|
|
147
|
+
children: [
|
|
148
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ClipboardCopy, { "aria-hidden": "true" }),
|
|
149
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Kopi\xE9r XML" })
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
) })
|
|
153
|
+
] })
|
|
154
|
+
}
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
),
|
|
158
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
159
|
+
"pre",
|
|
160
|
+
{
|
|
161
|
+
className: [styles__default.default.codePane, styles__default.default[size], wrap ? styles__default.default.wrap : styles__default.default.noWrap].join(" "),
|
|
162
|
+
tabIndex: 0,
|
|
163
|
+
onDoubleClick: handleDoubleClick,
|
|
164
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("code", { ref: codeRef, children: viewMode === "raw" ? xml : tokens.map((token, index) => {
|
|
165
|
+
const tokenClassName = TOKEN_CLASS[token.type];
|
|
166
|
+
return tokenClassName ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: tokenClassName, children: token.value }, index) : token.value;
|
|
167
|
+
}) })
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
exports.XmlViewer = XmlViewer;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
export type XmlViewerAppearance = 'dark' | 'light';
|
|
3
|
+
export interface XmlViewerProps {
|
|
4
|
+
xml: string;
|
|
5
|
+
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
6
|
+
/** Initial appearance. The user can toggle it via the kebab menu; defaults to 'dark'. */
|
|
7
|
+
appearance?: XmlViewerAppearance;
|
|
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 XmlViewer({ xml, size, appearance, storageKey, borderless, }: XmlViewerProps): JSX.Element;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
3
|
+
import { TextWrap, ListTree, Code2, Sun, Moon, ClipboardCopy, MoreVertical } from 'lucide-react';
|
|
4
|
+
import { useMemo, useRef } from 'react';
|
|
5
|
+
import { Menu } from '../../components/menu/Menu';
|
|
6
|
+
import { Popover } from '../../components/popover/Popover';
|
|
7
|
+
import { usePersistentState } from '../../hooks/usePersistentState';
|
|
8
|
+
import { tokenizeXml } from './tokenizeXml';
|
|
9
|
+
import styles from './XmlViewer.module.css';
|
|
10
|
+
import { Button } from '../button/Button';
|
|
11
|
+
|
|
12
|
+
const TOKEN_CLASS = {
|
|
13
|
+
tagName: styles.tagName,
|
|
14
|
+
attrName: styles.attrName,
|
|
15
|
+
attrValue: styles.attrValue,
|
|
16
|
+
comment: styles.comment,
|
|
17
|
+
cdata: styles.cdata,
|
|
18
|
+
declaration: styles.declaration,
|
|
19
|
+
doctype: styles.doctype,
|
|
20
|
+
punctuation: styles.punctuation,
|
|
21
|
+
text: void 0
|
|
22
|
+
};
|
|
23
|
+
function XmlViewer({
|
|
24
|
+
xml,
|
|
25
|
+
size = "md",
|
|
26
|
+
appearance = "dark",
|
|
27
|
+
storageKey,
|
|
28
|
+
borderless = false
|
|
29
|
+
}) {
|
|
30
|
+
const tokens = useMemo(() => tokenizeXml(xml), [xml]);
|
|
31
|
+
const codeRef = useRef(null);
|
|
32
|
+
const { value: currentAppearance, setValue: setCurrentAppearance } = usePersistentState({
|
|
33
|
+
initialValue: appearance,
|
|
34
|
+
storageKey: storageKey ? `${storageKey}:appearance` : void 0,
|
|
35
|
+
validate: (stored) => stored === "dark" || stored === "light"
|
|
36
|
+
});
|
|
37
|
+
const { value: viewMode, setValue: setViewMode } = usePersistentState({
|
|
38
|
+
initialValue: "highlighted",
|
|
39
|
+
storageKey: storageKey ? `${storageKey}:viewMode` : void 0,
|
|
40
|
+
validate: (stored) => stored === "highlighted" || stored === "raw"
|
|
41
|
+
});
|
|
42
|
+
const { value: wrap, setValue: setWrap } = usePersistentState({
|
|
43
|
+
initialValue: true,
|
|
44
|
+
storageKey: storageKey ? `${storageKey}:wrap` : void 0,
|
|
45
|
+
validate: (stored) => typeof stored === "boolean"
|
|
46
|
+
});
|
|
47
|
+
const handleCopy = () => {
|
|
48
|
+
var _a;
|
|
49
|
+
(_a = navigator.clipboard) == null ? void 0 : _a.writeText(xml).catch(() => {
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const handleDoubleClick = () => {
|
|
53
|
+
const el = codeRef.current;
|
|
54
|
+
const selection = typeof window !== "undefined" ? window.getSelection() : null;
|
|
55
|
+
if (!el || !selection) return;
|
|
56
|
+
const range = document.createRange();
|
|
57
|
+
range.selectNodeContents(el);
|
|
58
|
+
selection.removeAllRanges();
|
|
59
|
+
selection.addRange(range);
|
|
60
|
+
};
|
|
61
|
+
return /* @__PURE__ */ jsxs(
|
|
62
|
+
"section",
|
|
63
|
+
{
|
|
64
|
+
className: [styles.viewer, borderless ? styles.borderless : ""].filter(Boolean).join(" "),
|
|
65
|
+
"data-appearance": currentAppearance,
|
|
66
|
+
children: [
|
|
67
|
+
/* @__PURE__ */ jsx(
|
|
68
|
+
"div",
|
|
69
|
+
{
|
|
70
|
+
className: styles.toolbar,
|
|
71
|
+
"data-surface": currentAppearance === "dark" ? "inverse" : void 0,
|
|
72
|
+
children: /* @__PURE__ */ jsx(
|
|
73
|
+
Popover,
|
|
74
|
+
{
|
|
75
|
+
matchTriggerWidth: false,
|
|
76
|
+
minWidth: "200px",
|
|
77
|
+
trigger: (toggle, _icon, isOpen) => /* @__PURE__ */ jsx(
|
|
78
|
+
Button,
|
|
79
|
+
{
|
|
80
|
+
variant: "inline",
|
|
81
|
+
"aria-label": "Flere handlinger",
|
|
82
|
+
"aria-haspopup": "menu",
|
|
83
|
+
"aria-expanded": isOpen ? true : false,
|
|
84
|
+
onClick: toggle,
|
|
85
|
+
children: /* @__PURE__ */ jsx(MoreVertical, { "aria-hidden": "true" })
|
|
86
|
+
}
|
|
87
|
+
),
|
|
88
|
+
children: (close) => /* @__PURE__ */ jsxs(Menu, { children: [
|
|
89
|
+
/* @__PURE__ */ jsx(Menu.Item, { children: /* @__PURE__ */ jsxs(
|
|
90
|
+
"button",
|
|
91
|
+
{
|
|
92
|
+
type: "button",
|
|
93
|
+
onClick: () => {
|
|
94
|
+
setWrap((value) => !value);
|
|
95
|
+
close();
|
|
96
|
+
},
|
|
97
|
+
children: [
|
|
98
|
+
/* @__PURE__ */ jsx(TextWrap, { "aria-hidden": "true" }),
|
|
99
|
+
/* @__PURE__ */ jsx("span", { children: wrap ? "Ombryd ikke tekst" : "Ombryd tekst" })
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
) }),
|
|
103
|
+
/* @__PURE__ */ jsx(Menu.Separator, {}),
|
|
104
|
+
/* @__PURE__ */ jsx(Menu.Item, { children: /* @__PURE__ */ jsxs(
|
|
105
|
+
"button",
|
|
106
|
+
{
|
|
107
|
+
type: "button",
|
|
108
|
+
onClick: () => {
|
|
109
|
+
setViewMode((mode) => mode === "raw" ? "highlighted" : "raw");
|
|
110
|
+
close();
|
|
111
|
+
},
|
|
112
|
+
children: [
|
|
113
|
+
viewMode === "raw" ? /* @__PURE__ */ jsx(ListTree, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Code2, { "aria-hidden": "true" }),
|
|
114
|
+
/* @__PURE__ */ jsx("span", { children: viewMode === "raw" ? "Vis med farver" : "Vis raw" })
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
) }),
|
|
118
|
+
/* @__PURE__ */ jsx(Menu.Item, { children: /* @__PURE__ */ jsxs(
|
|
119
|
+
"button",
|
|
120
|
+
{
|
|
121
|
+
type: "button",
|
|
122
|
+
onClick: () => {
|
|
123
|
+
setCurrentAppearance((value) => value === "dark" ? "light" : "dark");
|
|
124
|
+
close();
|
|
125
|
+
},
|
|
126
|
+
children: [
|
|
127
|
+
currentAppearance === "dark" ? /* @__PURE__ */ jsx(Sun, { "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Moon, { "aria-hidden": "true" }),
|
|
128
|
+
/* @__PURE__ */ jsx("span", { children: currentAppearance === "dark" ? "Lys visning" : "M\xF8rk visning" })
|
|
129
|
+
]
|
|
130
|
+
}
|
|
131
|
+
) }),
|
|
132
|
+
/* @__PURE__ */ jsx(Menu.Separator, {}),
|
|
133
|
+
/* @__PURE__ */ jsx(Menu.Item, { children: /* @__PURE__ */ jsxs(
|
|
134
|
+
"button",
|
|
135
|
+
{
|
|
136
|
+
type: "button",
|
|
137
|
+
onClick: () => {
|
|
138
|
+
handleCopy();
|
|
139
|
+
close();
|
|
140
|
+
},
|
|
141
|
+
children: [
|
|
142
|
+
/* @__PURE__ */ jsx(ClipboardCopy, { "aria-hidden": "true" }),
|
|
143
|
+
/* @__PURE__ */ jsx("span", { children: "Kopi\xE9r XML" })
|
|
144
|
+
]
|
|
145
|
+
}
|
|
146
|
+
) })
|
|
147
|
+
] })
|
|
148
|
+
}
|
|
149
|
+
)
|
|
150
|
+
}
|
|
151
|
+
),
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
"pre",
|
|
154
|
+
{
|
|
155
|
+
className: [styles.codePane, styles[size], wrap ? styles.wrap : styles.noWrap].join(" "),
|
|
156
|
+
tabIndex: 0,
|
|
157
|
+
onDoubleClick: handleDoubleClick,
|
|
158
|
+
children: /* @__PURE__ */ jsx("code", { ref: codeRef, children: viewMode === "raw" ? xml : tokens.map((token, index) => {
|
|
159
|
+
const tokenClassName = TOKEN_CLASS[token.type];
|
|
160
|
+
return tokenClassName ? /* @__PURE__ */ jsx("span", { className: tokenClassName, children: token.value }, index) : token.value;
|
|
161
|
+
}) })
|
|
162
|
+
}
|
|
163
|
+
)
|
|
164
|
+
]
|
|
165
|
+
}
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export { XmlViewer };
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
.viewer {
|
|
2
|
+
--xml-pane-bg: var(--color-bg-inverse);
|
|
3
|
+
--xml-pane-border: color-mix(in oklab, var(--color-fg-inverse) 12%, transparent);
|
|
4
|
+
--xml-pane-text: var(--color-fg-inverse);
|
|
5
|
+
|
|
6
|
+
--xml-tag: color-mix(in oklab, var(--color-fg-inverse) 66%, var(--color-syntax-accent) 34%);
|
|
7
|
+
--xml-attr-name: color-mix(in oklab, var(--color-fg-inverse) 50%, var(--color-syntax-accent) 50%);
|
|
8
|
+
--xml-attr-value: color-mix(in oklab, var(--color-fg-inverse) 20%, var(--color-syntax-string) 80%);
|
|
9
|
+
--xml-comment: color-mix(in oklab, var(--color-fg-inverse) 46%, transparent);
|
|
10
|
+
--xml-punctuation: color-mix(in oklab, var(--color-fg-inverse) 60%, transparent);
|
|
11
|
+
|
|
12
|
+
position: relative;
|
|
13
|
+
background: var(--xml-pane-bg);
|
|
14
|
+
border: var(--border-width-thin) solid var(--xml-pane-border);
|
|
15
|
+
border-radius: var(--border-radius-default);
|
|
16
|
+
box-shadow: var(--shadow-md);
|
|
17
|
+
font-family: var(--font-family-mono);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.viewer[data-appearance='light'] {
|
|
21
|
+
--xml-pane-bg: var(--color-bg-surface);
|
|
22
|
+
--xml-pane-border: var(--color-border-subtle);
|
|
23
|
+
--xml-pane-text: var(--color-fg-default);
|
|
24
|
+
|
|
25
|
+
--xml-tag: var(--color-link);
|
|
26
|
+
--xml-attr-name: color-mix(in oklab, var(--color-fg-default) 55%, var(--color-link) 45%);
|
|
27
|
+
--xml-attr-value: var(--color-status-success-fg);
|
|
28
|
+
--xml-comment: var(--color-fg-muted);
|
|
29
|
+
--xml-punctuation: var(--color-fg-subtle);
|
|
30
|
+
|
|
31
|
+
box-shadow: var(--shadow-xs);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.viewer.borderless {
|
|
35
|
+
border: none;
|
|
36
|
+
border-radius: 0;
|
|
37
|
+
box-shadow: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.toolbar {
|
|
41
|
+
position: absolute;
|
|
42
|
+
top: var(--spacing-xs);
|
|
43
|
+
right: var(--spacing-xs);
|
|
44
|
+
z-index: 1;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.codePane {
|
|
48
|
+
margin: 0;
|
|
49
|
+
padding: var(--spacing-sm);
|
|
50
|
+
overflow: auto;
|
|
51
|
+
color: var(--xml-pane-text);
|
|
52
|
+
font-family: inherit;
|
|
53
|
+
line-height: 1.35;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.wrap {
|
|
57
|
+
white-space: pre-wrap;
|
|
58
|
+
overflow-wrap: break-word;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.noWrap {
|
|
62
|
+
white-space: pre;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.xs,
|
|
66
|
+
.sm {
|
|
67
|
+
font-size: var(--font-size-xs);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.md {
|
|
71
|
+
font-size: var(--font-size-sm);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.lg {
|
|
75
|
+
font-size: var(--font-size-base);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.tagName {
|
|
79
|
+
color: var(--xml-tag);
|
|
80
|
+
font-weight: var(--font-weight-medium);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.attrName {
|
|
84
|
+
color: var(--xml-attr-name);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.attrValue {
|
|
88
|
+
color: var(--xml-attr-value);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.comment {
|
|
92
|
+
color: var(--xml-comment);
|
|
93
|
+
font-style: italic;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.cdata {
|
|
97
|
+
color: var(--xml-attr-value);
|
|
98
|
+
opacity: 0.85;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.declaration,
|
|
102
|
+
.doctype {
|
|
103
|
+
color: var(--xml-comment);
|
|
104
|
+
font-style: italic;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.punctuation {
|
|
108
|
+
color: var(--xml-punctuation);
|
|
109
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const CHUNK_PATTERN = /(<!--[\s\S]*?-->)|(<!\[CDATA\[[\s\S]*?\]\]>)|(<!DOCTYPE[\s\S]*?>)|(<\?[\s\S]*?\?>)|(<\/?[a-zA-Z_:][\s\S]*?>)|([^<]+)/g;
|
|
4
|
+
const ATTR_PATTERN = /([^\s=/>]+)(\s*=\s*)("[^"]*"|'[^']*')/g;
|
|
5
|
+
function tokenizeTag(raw) {
|
|
6
|
+
var _a;
|
|
7
|
+
const isClosing = raw.startsWith("</");
|
|
8
|
+
const isSelfClosing = raw.endsWith("/>");
|
|
9
|
+
const openLength = isClosing ? 2 : 1;
|
|
10
|
+
const closeLength = isSelfClosing ? 2 : 1;
|
|
11
|
+
const inner = raw.slice(openLength, raw.length - closeLength);
|
|
12
|
+
const tokens = [{ type: "punctuation", value: raw.slice(0, openLength) }];
|
|
13
|
+
const nameMatch = /^[^\s/>]+/.exec(inner);
|
|
14
|
+
const name = (_a = nameMatch == null ? void 0 : nameMatch[0]) != null ? _a : "";
|
|
15
|
+
if (name) tokens.push({ type: "tagName", value: name });
|
|
16
|
+
let lastIndex = name.length;
|
|
17
|
+
ATTR_PATTERN.lastIndex = lastIndex;
|
|
18
|
+
let match;
|
|
19
|
+
while (match = ATTR_PATTERN.exec(inner)) {
|
|
20
|
+
if (match.index > lastIndex) {
|
|
21
|
+
tokens.push({ type: "punctuation", value: inner.slice(lastIndex, match.index) });
|
|
22
|
+
}
|
|
23
|
+
tokens.push({ type: "attrName", value: match[1] });
|
|
24
|
+
tokens.push({ type: "punctuation", value: match[2] });
|
|
25
|
+
tokens.push({ type: "attrValue", value: match[3] });
|
|
26
|
+
lastIndex = match.index + match[0].length;
|
|
27
|
+
}
|
|
28
|
+
if (lastIndex < inner.length) {
|
|
29
|
+
tokens.push({ type: "punctuation", value: inner.slice(lastIndex) });
|
|
30
|
+
}
|
|
31
|
+
tokens.push({ type: "punctuation", value: raw.slice(raw.length - closeLength) });
|
|
32
|
+
return tokens;
|
|
33
|
+
}
|
|
34
|
+
function tokenizeXml(source) {
|
|
35
|
+
const tokens = [];
|
|
36
|
+
CHUNK_PATTERN.lastIndex = 0;
|
|
37
|
+
let match;
|
|
38
|
+
while (match = CHUNK_PATTERN.exec(source)) {
|
|
39
|
+
const [, comment, cdata, doctype, declaration, tag, text] = match;
|
|
40
|
+
if (comment) tokens.push({ type: "comment", value: comment });
|
|
41
|
+
else if (cdata) tokens.push({ type: "cdata", value: cdata });
|
|
42
|
+
else if (doctype) tokens.push({ type: "doctype", value: doctype });
|
|
43
|
+
else if (declaration) tokens.push({ type: "declaration", value: declaration });
|
|
44
|
+
else if (tag) tokens.push(...tokenizeTag(tag));
|
|
45
|
+
else if (text) tokens.push({ type: "text", value: text });
|
|
46
|
+
}
|
|
47
|
+
return tokens;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
exports.tokenizeXml = tokenizeXml;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type XmlTokenType = 'tagName' | 'attrName' | 'attrValue' | 'text' | 'comment' | 'cdata' | 'declaration' | 'doctype' | 'punctuation';
|
|
2
|
+
export interface XmlToken {
|
|
3
|
+
type: XmlTokenType;
|
|
4
|
+
value: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Tokenizes an XML string for syntax highlighting without parsing it into a
|
|
8
|
+
* DOM. Preserves the source exactly - concatenating every token's `value`
|
|
9
|
+
* reproduces the input - so malformed or partial XML still highlights
|
|
10
|
+
* whatever it recognizes instead of failing outright.
|
|
11
|
+
*/
|
|
12
|
+
export declare function tokenizeXml(source: string): XmlToken[];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const CHUNK_PATTERN = /(<!--[\s\S]*?-->)|(<!\[CDATA\[[\s\S]*?\]\]>)|(<!DOCTYPE[\s\S]*?>)|(<\?[\s\S]*?\?>)|(<\/?[a-zA-Z_:][\s\S]*?>)|([^<]+)/g;
|
|
2
|
+
const ATTR_PATTERN = /([^\s=/>]+)(\s*=\s*)("[^"]*"|'[^']*')/g;
|
|
3
|
+
function tokenizeTag(raw) {
|
|
4
|
+
var _a;
|
|
5
|
+
const isClosing = raw.startsWith("</");
|
|
6
|
+
const isSelfClosing = raw.endsWith("/>");
|
|
7
|
+
const openLength = isClosing ? 2 : 1;
|
|
8
|
+
const closeLength = isSelfClosing ? 2 : 1;
|
|
9
|
+
const inner = raw.slice(openLength, raw.length - closeLength);
|
|
10
|
+
const tokens = [{ type: "punctuation", value: raw.slice(0, openLength) }];
|
|
11
|
+
const nameMatch = /^[^\s/>]+/.exec(inner);
|
|
12
|
+
const name = (_a = nameMatch == null ? void 0 : nameMatch[0]) != null ? _a : "";
|
|
13
|
+
if (name) tokens.push({ type: "tagName", value: name });
|
|
14
|
+
let lastIndex = name.length;
|
|
15
|
+
ATTR_PATTERN.lastIndex = lastIndex;
|
|
16
|
+
let match;
|
|
17
|
+
while (match = ATTR_PATTERN.exec(inner)) {
|
|
18
|
+
if (match.index > lastIndex) {
|
|
19
|
+
tokens.push({ type: "punctuation", value: inner.slice(lastIndex, match.index) });
|
|
20
|
+
}
|
|
21
|
+
tokens.push({ type: "attrName", value: match[1] });
|
|
22
|
+
tokens.push({ type: "punctuation", value: match[2] });
|
|
23
|
+
tokens.push({ type: "attrValue", value: match[3] });
|
|
24
|
+
lastIndex = match.index + match[0].length;
|
|
25
|
+
}
|
|
26
|
+
if (lastIndex < inner.length) {
|
|
27
|
+
tokens.push({ type: "punctuation", value: inner.slice(lastIndex) });
|
|
28
|
+
}
|
|
29
|
+
tokens.push({ type: "punctuation", value: raw.slice(raw.length - closeLength) });
|
|
30
|
+
return tokens;
|
|
31
|
+
}
|
|
32
|
+
function tokenizeXml(source) {
|
|
33
|
+
const tokens = [];
|
|
34
|
+
CHUNK_PATTERN.lastIndex = 0;
|
|
35
|
+
let match;
|
|
36
|
+
while (match = CHUNK_PATTERN.exec(source)) {
|
|
37
|
+
const [, comment, cdata, doctype, declaration, tag, text] = match;
|
|
38
|
+
if (comment) tokens.push({ type: "comment", value: comment });
|
|
39
|
+
else if (cdata) tokens.push({ type: "cdata", value: cdata });
|
|
40
|
+
else if (doctype) tokens.push({ type: "doctype", value: doctype });
|
|
41
|
+
else if (declaration) tokens.push({ type: "declaration", value: declaration });
|
|
42
|
+
else if (tag) tokens.push(...tokenizeTag(tag));
|
|
43
|
+
else if (text) tokens.push({ type: "text", value: text });
|
|
44
|
+
}
|
|
45
|
+
return tokens;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { tokenizeXml };
|
package/dist/index.cjs
CHANGED
|
@@ -43,6 +43,7 @@ var MediaCard = require('./components/media-card/MediaCard');
|
|
|
43
43
|
var HighlightedText = require('./components/highlighted-text/HighlightedText');
|
|
44
44
|
var ButtonSelect = require('./components/button-select/ButtonSelect');
|
|
45
45
|
var Sidebar = require('./components/sidebar/Sidebar');
|
|
46
|
+
var TreeView = require('./components/tree-view/TreeView');
|
|
46
47
|
var SplitButton = require('./components/split-button/SplitButton');
|
|
47
48
|
var ChipMultiToggle = require('./components/filtering/chip-multi-toggle/ChipMultiToggle');
|
|
48
49
|
var CheckboxGroup = require('./components/forms/checkbox-group/CheckboxGroup');
|
|
@@ -307,6 +308,12 @@ Object.keys(Sidebar).forEach(function (k) {
|
|
|
307
308
|
get: function () { return Sidebar[k]; }
|
|
308
309
|
});
|
|
309
310
|
});
|
|
311
|
+
Object.keys(TreeView).forEach(function (k) {
|
|
312
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
313
|
+
enumerable: true,
|
|
314
|
+
get: function () { return TreeView[k]; }
|
|
315
|
+
});
|
|
316
|
+
});
|
|
310
317
|
Object.keys(SplitButton).forEach(function (k) {
|
|
311
318
|
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
312
319
|
enumerable: true,
|
package/dist/index.css
CHANGED
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
@import './components/inline-status/InlineStatus.module.css';
|
|
40
40
|
@import './components/json-viewer/JsonViewer.module.css';
|
|
41
41
|
@import './components/lightbox/Lightbox.module.css';
|
|
42
|
+
@import './components/line-viewer/LineViewer.module.css';
|
|
42
43
|
@import './components/media-card/MediaCard.module.css';
|
|
43
44
|
@import './components/menu/Menu.module.css';
|
|
44
45
|
@import './components/meta-bar/MetaBar.module.css';
|
|
@@ -72,4 +73,6 @@
|
|
|
72
73
|
@import './components/table/components/empty-state/EmptyState.module.css';
|
|
73
74
|
@import './components/tabs/Tabs.module.css';
|
|
74
75
|
@import './components/toast/Toast.module.css';
|
|
76
|
+
@import './components/tree-view/TreeView.module.css';
|
|
75
77
|
@import './components/user-display/UserDisplay.module.css';
|
|
78
|
+
@import './components/xml-viewer/XmlViewer.module.css';
|
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export * from './components/media-card/MediaCard';
|
|
|
42
42
|
export * from './components/highlighted-text/HighlightedText';
|
|
43
43
|
export * from './components/button-select/ButtonSelect';
|
|
44
44
|
export * from './components/sidebar/Sidebar';
|
|
45
|
+
export * from './components/tree-view/TreeView';
|
|
45
46
|
export * from './components/split-button/SplitButton';
|
|
46
47
|
export * from './components/filtering/chip-multi-toggle/ChipMultiToggle';
|
|
47
48
|
export * from './components/forms/checkbox-group/CheckboxGroup';
|
package/dist/index.js
CHANGED
|
@@ -41,6 +41,7 @@ export * from './components/media-card/MediaCard';
|
|
|
41
41
|
export * from './components/highlighted-text/HighlightedText';
|
|
42
42
|
export * from './components/button-select/ButtonSelect';
|
|
43
43
|
export * from './components/sidebar/Sidebar';
|
|
44
|
+
export * from './components/tree-view/TreeView';
|
|
44
45
|
export * from './components/split-button/SplitButton';
|
|
45
46
|
export * from './components/filtering/chip-multi-toggle/ChipMultiToggle';
|
|
46
47
|
export * from './components/forms/checkbox-group/CheckboxGroup';
|