@dxos/react-ui-syntax-highlighter 0.12.0-next-73daef452f1464b62efdbca75fb0067c1066f264 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/index.mjs +197 -63
- package/dist/lib/index.mjs.map +1 -1
- package/dist/types/src/JsonHighlighter/JsonHighlighter.d.ts +4 -4
- package/dist/types/src/JsonHighlighter/JsonHighlighter.d.ts.map +1 -1
- package/dist/types/src/JsonHighlighter/JsonHighlighter.stories.d.ts +2 -2
- package/dist/types/src/JsonHighlighter/JsonHighlighter.stories.d.ts.map +1 -1
- package/dist/types/src/JsonHighlighter/index.d.ts +1 -1
- package/dist/types/src/JsonHighlighter/index.d.ts.map +1 -1
- package/dist/types/src/Syntax/Syntax.d.ts +5 -10
- package/dist/types/src/Syntax/Syntax.d.ts.map +1 -1
- package/dist/types/src/Syntax/Syntax.stories.d.ts +1 -1
- package/dist/types/src/Syntax/SyntaxContext.d.ts +3 -12
- package/dist/types/src/Syntax/SyntaxContext.d.ts.map +1 -1
- package/dist/types/src/Syntax/index.d.ts +1 -2
- package/dist/types/src/Syntax/index.d.ts.map +1 -1
- package/dist/types/src/SyntaxHighlighter/SyntaxHighlighter.d.ts +8 -4
- package/dist/types/src/SyntaxHighlighter/SyntaxHighlighter.d.ts.map +1 -1
- package/dist/types/src/SyntaxHighlighter/SyntaxHighlighter.stories.d.ts +2 -2
- package/dist/types/src/SyntaxHighlighter/SyntaxHighlighter.stories.d.ts.map +1 -1
- package/dist/types/src/SyntaxHighlighter/index.d.ts +1 -1
- package/dist/types/src/SyntaxHighlighter/index.d.ts.map +1 -1
- package/dist/types/src/SyntaxHighlighter/renderer.d.ts +10 -0
- package/dist/types/src/SyntaxHighlighter/renderer.d.ts.map +1 -0
- package/dist/types/src/SyntaxHighlighter/renderer.test.d.ts +2 -0
- package/dist/types/src/SyntaxHighlighter/renderer.test.d.ts.map +1 -0
- package/dist/types/src/index.d.ts +3 -3
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -11
- package/src/JsonHighlighter/JsonHighlighter.stories.tsx +1 -1
- package/src/JsonHighlighter/JsonHighlighter.tsx +7 -6
- package/src/JsonHighlighter/index.ts +1 -1
- package/src/Syntax/Syntax.stories.tsx +1 -1
- package/src/Syntax/Syntax.tsx +59 -60
- package/src/Syntax/SyntaxContext.ts +3 -6
- package/src/Syntax/index.ts +1 -3
- package/src/SyntaxHighlighter/SyntaxHighlighter.stories.tsx +1 -1
- package/src/SyntaxHighlighter/SyntaxHighlighter.tsx +137 -39
- package/src/SyntaxHighlighter/index.ts +1 -1
- package/src/SyntaxHighlighter/renderer.test.tsx +52 -0
- package/src/SyntaxHighlighter/renderer.ts +118 -0
- package/src/index.ts +3 -3
package/dist/lib/index.mjs
CHANGED
|
@@ -1,13 +1,96 @@
|
|
|
1
|
-
import { Children, forwardRef, useCallback, useMemo, useState } from "react";
|
|
2
|
-
import
|
|
1
|
+
import { Children, createElement as createElement$1, forwardRef, memo, useCallback, useMemo, useState } from "react";
|
|
2
|
+
import * as Util from "@dxos/react-ui/Util";
|
|
3
3
|
import { createReplacer, safeStringify } from "@dxos/util";
|
|
4
4
|
import createElement from "react-syntax-highlighter/dist/esm/create-element";
|
|
5
5
|
import NativeSyntaxHighlighter from "react-syntax-highlighter/dist/esm/prism-async-light";
|
|
6
6
|
import { coldarkCold, coldarkDark } from "react-syntax-highlighter/dist/esm/styles/prism";
|
|
7
|
+
import * as Hooks from "@dxos/react-ui/Hooks";
|
|
8
|
+
import * as ScrollArea from "@dxos/react-ui/ScrollArea";
|
|
9
|
+
import * as SystemButton from "@dxos/react-ui/SystemButton";
|
|
7
10
|
import { mx } from "@dxos/ui-theme";
|
|
8
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
|
-
import { createContextScope } from "@radix-ui/react-context";
|
|
10
12
|
import { JSONPath } from "jsonpath-plus";
|
|
13
|
+
import * as Field from "@dxos/react-ui/Field";
|
|
14
|
+
import * as Input from "@dxos/react-ui/Input";
|
|
15
|
+
import { createContext } from "@dxos/react-hooks";
|
|
16
|
+
//#region src/SyntaxHighlighter/renderer.ts
|
|
17
|
+
var indexes = /* @__PURE__ */ new WeakMap();
|
|
18
|
+
var indexOf = (stylesheet) => {
|
|
19
|
+
let index = indexes.get(stylesheet);
|
|
20
|
+
if (!index) {
|
|
21
|
+
const selectors = /* @__PURE__ */ new Set();
|
|
22
|
+
for (const selector of Object.keys(stylesheet)) for (const className of selector.split(".")) selectors.add(className);
|
|
23
|
+
index = {
|
|
24
|
+
selectors,
|
|
25
|
+
styles: /* @__PURE__ */ new Map()
|
|
26
|
+
};
|
|
27
|
+
indexes.set(stylesheet, index);
|
|
28
|
+
}
|
|
29
|
+
return index;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Every ordered selection of one to four class names, shortest first — the selector keys a
|
|
33
|
+
* compound class list can match, in the precedence order `react-syntax-highlighter` applies them.
|
|
34
|
+
*/
|
|
35
|
+
var classNameCombinations = (classNames) => {
|
|
36
|
+
const pool = classNames.slice(0, 4);
|
|
37
|
+
const combinations = [];
|
|
38
|
+
const extend = (prefix, remaining, size) => {
|
|
39
|
+
if (prefix.length === size) {
|
|
40
|
+
combinations.push(prefix.join("."));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
for (const position of remaining) extend([...prefix, pool[position]], remaining.filter((other) => other !== position), size);
|
|
44
|
+
};
|
|
45
|
+
const positions = pool.map((_, position) => position);
|
|
46
|
+
for (let size = 1; size <= pool.length; size++) extend([], positions, size);
|
|
47
|
+
return combinations;
|
|
48
|
+
};
|
|
49
|
+
var styleOf = (index, stylesheet, classNames) => {
|
|
50
|
+
const key = classNames.join(" ");
|
|
51
|
+
let style = index.styles.get(key);
|
|
52
|
+
if (!style) {
|
|
53
|
+
style = {};
|
|
54
|
+
for (const selector of classNameCombinations(classNames.filter((className) => className !== "token"))) Object.assign(style, stylesheet[selector]);
|
|
55
|
+
index.styles.set(key, style);
|
|
56
|
+
}
|
|
57
|
+
return style;
|
|
58
|
+
};
|
|
59
|
+
var renderNode = (node, stylesheet, useInlineStyles, key) => {
|
|
60
|
+
if (node.type === "text") return node.value;
|
|
61
|
+
if (!node.tagName) return;
|
|
62
|
+
const properties = node.properties ?? { className: [] };
|
|
63
|
+
const classNames = properties.className ?? [];
|
|
64
|
+
let props;
|
|
65
|
+
if (!useInlineStyles) props = {
|
|
66
|
+
...properties,
|
|
67
|
+
className: classNames.join(" ")
|
|
68
|
+
};
|
|
69
|
+
else {
|
|
70
|
+
const index = indexOf(stylesheet);
|
|
71
|
+
const className = [...classNames.includes("token") ? ["token"] : [], ...classNames.filter((name) => !index.selectors.has(name))].join(" ");
|
|
72
|
+
props = {
|
|
73
|
+
...properties,
|
|
74
|
+
className: className || void 0,
|
|
75
|
+
style: {
|
|
76
|
+
...properties.style,
|
|
77
|
+
...styleOf(index, stylesheet, classNames)
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const children = (node.children ?? []).map((child, position) => renderNode(child, stylesheet, useInlineStyles, `code-segment-1-${position}`));
|
|
82
|
+
return createElement$1(node.tagName, {
|
|
83
|
+
key,
|
|
84
|
+
...props
|
|
85
|
+
}, children);
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Drop-in for `react-syntax-highlighter`'s default row renderer, producing the same elements.
|
|
89
|
+
* The stock renderer rebuilds the stylesheet's full selector list (a quadratic scan) for every
|
|
90
|
+
* token node, which dominated the main thread whenever a highlighted block re-rendered.
|
|
91
|
+
*/
|
|
92
|
+
var renderRows = ({ rows, stylesheet, useInlineStyles }) => rows.map((row, position) => renderNode(row, stylesheet, useInlineStyles, `code-segment-${position}`));
|
|
93
|
+
//#endregion
|
|
11
94
|
//#region src/SyntaxHighlighter/SyntaxHighlighter.tsx
|
|
12
95
|
var zeroWidthSpace = "";
|
|
13
96
|
var languages = {
|
|
@@ -15,10 +98,15 @@ var languages = {
|
|
|
15
98
|
ts: "typescript"
|
|
16
99
|
};
|
|
17
100
|
/**
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
101
|
+
* Above this, source is rendered unhighlighted. react-syntax-highlighter splices every line into a
|
|
102
|
+
* single token array and wraps every token in an inline-styled element, so tokenizing grows
|
|
103
|
+
* super-linearly in one synchronous render — a 3 MB payload takes about 30 s, and past roughly 123k
|
|
104
|
+
* lines it throws. Plain text skips the tokenizer and keeps this component's own `pre`/`code` styles.
|
|
105
|
+
*/
|
|
106
|
+
var MAX_HIGHLIGHTED_LENGTH = 2e4;
|
|
107
|
+
/**
|
|
108
|
+
* Highlighted source inside the family's themed `ScrollArea`, so a long line scrolls with the thin
|
|
109
|
+
* scrollbar rather than the platform's. Pass `scroll={false}` to get the bare leaf.
|
|
22
110
|
*
|
|
23
111
|
* NOTE: Using `light-async` version directly from dist to avoid any chance of the heavy one being loaded.
|
|
24
112
|
* The lightweight version will load specific language parsers asynchronously.
|
|
@@ -26,45 +114,97 @@ var languages = {
|
|
|
26
114
|
* https://github.com/react-syntax-highlighter/react-syntax-highlighter
|
|
27
115
|
* https://react-syntax-highlighter.github.io/react-syntax-highlighter/demo/prism.html
|
|
28
116
|
*/
|
|
29
|
-
var SyntaxHighlighter = composable(({
|
|
30
|
-
|
|
31
|
-
|
|
117
|
+
var SyntaxHighlighter = Util.composable(({ scroll = "all", copyButton, classNames, className, role, style, ...props }, forwardedRef) => {
|
|
118
|
+
if (scroll === false) return /* @__PURE__ */ jsx(SyntaxHighlighterLeaf, {
|
|
119
|
+
...props,
|
|
120
|
+
classNames,
|
|
121
|
+
className,
|
|
122
|
+
role,
|
|
123
|
+
style,
|
|
124
|
+
copyButton,
|
|
125
|
+
ref: forwardedRef
|
|
126
|
+
});
|
|
127
|
+
const source = sourceOf(props.children, props.fallback);
|
|
128
|
+
return /* @__PURE__ */ jsxs(ScrollArea.Root, {
|
|
129
|
+
role: role ?? "none",
|
|
130
|
+
style,
|
|
131
|
+
classNames: [
|
|
132
|
+
className,
|
|
133
|
+
classNames,
|
|
134
|
+
copyButton && "relative group"
|
|
135
|
+
],
|
|
136
|
+
orientation: scroll,
|
|
137
|
+
ref: forwardedRef,
|
|
138
|
+
children: [/* @__PURE__ */ jsx(ScrollArea.Viewport, { children: /* @__PURE__ */ jsx(SyntaxHighlighterLeaf, { ...props }) }), copyButton && /* @__PURE__ */ jsx(CopyOverlay, { source })]
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
SyntaxHighlighter.displayName = "SyntaxHighlighter";
|
|
142
|
+
var sourceOf = (children, fallback = zeroWidthSpace) => Children.toArray(children).join("") || fallback;
|
|
143
|
+
var CopyOverlay = ({ source }) => /* @__PURE__ */ jsx("div", {
|
|
144
|
+
className: "pointer-events-none absolute top-1 right-1 z-10 opacity-0 group-hover:opacity-100 focus-within:opacity-100",
|
|
145
|
+
children: /* @__PURE__ */ jsx(SystemButton.Clipboard, {
|
|
146
|
+
iconOnly: true,
|
|
147
|
+
value: source,
|
|
148
|
+
variant: "ghost",
|
|
149
|
+
iconSize: "md",
|
|
150
|
+
classNames: "pointer-events-auto aspect-square rounded-sm"
|
|
151
|
+
})
|
|
152
|
+
});
|
|
153
|
+
/** The non-scrolling leaf: all scrolling is deferred to an enclosing viewport. */
|
|
154
|
+
var SyntaxHighlighterLeaf = Util.composable(({ classNames, className, children, role, style, themeStyle, language: languageProp = "text", fallback = zeroWidthSpace, copyButton, ...nativeProps }, forwardedRef) => {
|
|
155
|
+
const themeMode = Hooks.useThemeMode();
|
|
156
|
+
const source = sourceOf(children, fallback);
|
|
157
|
+
const language = source.length > MAX_HIGHLIGHTED_LENGTH ? "text" : languageProp;
|
|
32
158
|
const prismTheme = themeStyle && typeof themeStyle === "object" && Object.keys(themeStyle).length > 0 ? themeStyle : themeMode === "dark" ? coldarkDark : coldarkCold;
|
|
33
159
|
return /* @__PURE__ */ jsxs("div", {
|
|
34
|
-
...composableProps({
|
|
160
|
+
...Util.composableProps({
|
|
35
161
|
classNames,
|
|
36
162
|
className,
|
|
37
163
|
role,
|
|
38
164
|
style
|
|
39
165
|
}, {
|
|
40
166
|
role: "none",
|
|
41
|
-
classNames: mx("dx-
|
|
167
|
+
classNames: mx("dx-expand overflow-visible p-1", copyButton && "relative group")
|
|
42
168
|
}),
|
|
43
169
|
ref: forwardedRef,
|
|
44
|
-
children: [/* @__PURE__ */ jsx(
|
|
170
|
+
children: [/* @__PURE__ */ jsx(HighlightedSource, {
|
|
45
171
|
language: languages[language] || language,
|
|
46
172
|
style: prismTheme,
|
|
47
|
-
customStyle: {
|
|
48
|
-
background: "unset",
|
|
49
|
-
border: "none",
|
|
50
|
-
boxShadow: "none",
|
|
51
|
-
padding: 0,
|
|
52
|
-
margin: 0,
|
|
53
|
-
overflow: "visible"
|
|
54
|
-
},
|
|
55
173
|
...nativeProps,
|
|
56
174
|
children: source
|
|
57
|
-
}), copyButton && /* @__PURE__ */ jsx(
|
|
58
|
-
className: "pointer-events-none absolute top-1 right-1 z-10 opacity-0 group-hover:opacity-100 focus-within:opacity-100",
|
|
59
|
-
children: /* @__PURE__ */ jsx(Clipboard.Provider, { children: /* @__PURE__ */ jsx(Clipboard.IconButton, {
|
|
60
|
-
value: source,
|
|
61
|
-
variant: "ghost",
|
|
62
|
-
size: 4,
|
|
63
|
-
classNames: "pointer-events-auto aspect-square rounded-sm"
|
|
64
|
-
}) })
|
|
65
|
-
})]
|
|
175
|
+
}), copyButton && /* @__PURE__ */ jsx(CopyOverlay, { source })]
|
|
66
176
|
});
|
|
67
177
|
});
|
|
178
|
+
SyntaxHighlighterLeaf.displayName = "SyntaxHighlighterLeaf";
|
|
179
|
+
var customStyle = {
|
|
180
|
+
background: "unset",
|
|
181
|
+
border: "none",
|
|
182
|
+
boxShadow: "none",
|
|
183
|
+
padding: 0,
|
|
184
|
+
margin: 0,
|
|
185
|
+
lineHeight: "inherit",
|
|
186
|
+
overflow: "visible"
|
|
187
|
+
};
|
|
188
|
+
var codeTagProps = { style: {
|
|
189
|
+
lineHeight: "inherit",
|
|
190
|
+
display: "block"
|
|
191
|
+
} };
|
|
192
|
+
/**
|
|
193
|
+
* Memoized on primitive props because tokenizing and building the element tree is the expensive
|
|
194
|
+
* part, and streaming parents (e.g. the assistant's tool panel) re-render with unchanged source.
|
|
195
|
+
*/
|
|
196
|
+
var HighlightedSource = memo(({ children, renderer, wrapLines, ...props }) => /* @__PURE__ */ jsx(NativeSyntaxHighlighter, {
|
|
197
|
+
customStyle,
|
|
198
|
+
codeTagProps: {
|
|
199
|
+
...codeTagProps,
|
|
200
|
+
style: { ...codeTagProps?.style }
|
|
201
|
+
},
|
|
202
|
+
renderer: renderer ?? renderRows,
|
|
203
|
+
wrapLines: wrapLines ?? (renderer ? void 0 : false),
|
|
204
|
+
...props,
|
|
205
|
+
children
|
|
206
|
+
}));
|
|
207
|
+
HighlightedSource.displayName = "HighlightedSource";
|
|
68
208
|
SyntaxHighlighter.displayName = "SyntaxHighlighter";
|
|
69
209
|
//#endregion
|
|
70
210
|
//#region src/JsonHighlighter/JsonHighlighter.tsx
|
|
@@ -73,14 +213,14 @@ var resolveReplacer = (replacer) => {
|
|
|
73
213
|
return typeof replacer === "function" ? replacer : createReplacer(replacer);
|
|
74
214
|
};
|
|
75
215
|
/**
|
|
76
|
-
*
|
|
216
|
+
* JSON in the family's themed `ScrollArea`: the shorthand for showing a value.
|
|
77
217
|
*
|
|
78
218
|
* Thin wrapper around `SyntaxHighlighter` that stringifies `data` with an optional replacer.
|
|
79
219
|
* `replacer` accepts either `CreateReplacerProps` (declarative truncation) or a raw
|
|
80
|
-
* `JSON.stringify`-compatible function (for bespoke serialization).
|
|
81
|
-
*
|
|
220
|
+
* `JSON.stringify`-compatible function (for bespoke serialization). `scroll` picks the axes
|
|
221
|
+
* (default: all). Compose with the `Syntax.*` namespace only for filtering or a depth control.
|
|
82
222
|
*/
|
|
83
|
-
var JsonHighlighter = composable(({ data, replacer, indent = 2, testId, ...props }, forwardedRef) => {
|
|
223
|
+
var JsonHighlighter = Util.composable(({ data, replacer, indent = 2, testId, ...props }, forwardedRef) => {
|
|
84
224
|
return /* @__PURE__ */ jsx(SyntaxHighlighter, {
|
|
85
225
|
...props,
|
|
86
226
|
language: "json",
|
|
@@ -90,11 +230,7 @@ var JsonHighlighter = composable(({ data, replacer, indent = 2, testId, ...props
|
|
|
90
230
|
});
|
|
91
231
|
});
|
|
92
232
|
JsonHighlighter.displayName = "JsonHighlighter";
|
|
93
|
-
|
|
94
|
-
//#region src/Syntax/SyntaxContext.ts
|
|
95
|
-
var SYNTAX_NAME = "Syntax";
|
|
96
|
-
var [createSyntaxContext, createSyntaxScope] = createContextScope(SYNTAX_NAME);
|
|
97
|
-
var [SyntaxProvider, useSyntaxContext] = createSyntaxContext(SYNTAX_NAME);
|
|
233
|
+
var [SyntaxProvider, useSyntaxContext] = createContext("Syntax");
|
|
98
234
|
//#endregion
|
|
99
235
|
//#region src/Syntax/Syntax.tsx
|
|
100
236
|
var SYNTAX_ROOT_NAME = "Syntax.Root";
|
|
@@ -105,7 +241,7 @@ var SYNTAX_ROOT_NAME = "Syntax.Root";
|
|
|
105
241
|
* presence, not value.
|
|
106
242
|
*/
|
|
107
243
|
var SyntaxRoot = (props) => {
|
|
108
|
-
const {
|
|
244
|
+
const { children, language, source, replacer, getReplacer, defaultDepth = 0, onDepthChange } = props;
|
|
109
245
|
const isJson = "data" in props;
|
|
110
246
|
const data = props.data;
|
|
111
247
|
const [filterText, setFilterText] = useState("");
|
|
@@ -144,7 +280,6 @@ var SyntaxRoot = (props) => {
|
|
|
144
280
|
filterText
|
|
145
281
|
]);
|
|
146
282
|
return /* @__PURE__ */ jsx(SyntaxProvider, {
|
|
147
|
-
scope: __scopeSyntax,
|
|
148
283
|
mode: isJson ? "json" : "text",
|
|
149
284
|
source,
|
|
150
285
|
language,
|
|
@@ -162,9 +297,9 @@ var SyntaxRoot = (props) => {
|
|
|
162
297
|
SyntaxRoot.displayName = SYNTAX_ROOT_NAME;
|
|
163
298
|
var SYNTAX_CONTENT_NAME = "Syntax.Content";
|
|
164
299
|
/** Flex-column layout container for composite parts. */
|
|
165
|
-
var SyntaxContent = composable(({ children, ...props }, forwardedRef) => {
|
|
300
|
+
var SyntaxContent = Util.composable(({ children, ...props }, forwardedRef) => {
|
|
166
301
|
return /* @__PURE__ */ jsx("div", {
|
|
167
|
-
...composableProps(props, { classNames: "flex flex-col
|
|
302
|
+
...Util.composableProps(props, { classNames: "flex flex-col p-1 dx-expand overflow-hidden" }),
|
|
168
303
|
ref: forwardedRef,
|
|
169
304
|
children
|
|
170
305
|
});
|
|
@@ -172,12 +307,12 @@ var SyntaxContent = composable(({ children, ...props }, forwardedRef) => {
|
|
|
172
307
|
SyntaxContent.displayName = SYNTAX_CONTENT_NAME;
|
|
173
308
|
var SYNTAX_FILTER_NAME = "Syntax.Filter";
|
|
174
309
|
/** JSONPath filter input. Only meaningful when `Syntax.Root` is in JSON mode. */
|
|
175
|
-
var SyntaxFilter = forwardRef(({
|
|
176
|
-
const { mode, filterText, setFilterText, filterError } = useSyntaxContext(SYNTAX_FILTER_NAME
|
|
310
|
+
var SyntaxFilter = forwardRef(({ classNames, placeholder = "JSONPath (e.g., $.graph.nodes)" }, forwardedRef) => {
|
|
311
|
+
const { mode, filterText, setFilterText, filterError } = useSyntaxContext(SYNTAX_FILTER_NAME);
|
|
177
312
|
if (mode !== "json") throw new Error(`\`${SYNTAX_FILTER_NAME}\` requires \`Syntax.Root\` to be in JSON mode (pass \`data\`).`);
|
|
178
|
-
return /* @__PURE__ */ jsx(
|
|
313
|
+
return /* @__PURE__ */ jsx(Field.Root, {
|
|
179
314
|
validationValence: filterError ? "error" : "success",
|
|
180
|
-
children: /* @__PURE__ */ jsx(Input.
|
|
315
|
+
children: /* @__PURE__ */ jsx(Input.Root, {
|
|
181
316
|
classNames: [
|
|
182
317
|
"p-1 px-2 font-mono",
|
|
183
318
|
filterError && "border-rose-500",
|
|
@@ -197,40 +332,38 @@ var SYNTAX_DEPTH_NAME = "Syntax.Depth";
|
|
|
197
332
|
* Numeric expansion-depth control bound to `Syntax.Root`'s depth state. Meaningful when the Root is
|
|
198
333
|
* given a `getReplacer` that consumes depth (e.g. to resolve references N levels deep).
|
|
199
334
|
*/
|
|
200
|
-
var SyntaxDepth = forwardRef(({
|
|
201
|
-
const { depth, setDepth } = useSyntaxContext(SYNTAX_DEPTH_NAME
|
|
202
|
-
return /* @__PURE__ */ jsx(
|
|
203
|
-
classNames: ["
|
|
204
|
-
variant: "subdued",
|
|
205
|
-
type: "number",
|
|
335
|
+
var SyntaxDepth = forwardRef(({ classNames }, forwardedRef) => {
|
|
336
|
+
const { depth, setDepth } = useSyntaxContext(SYNTAX_DEPTH_NAME);
|
|
337
|
+
return /* @__PURE__ */ jsx(Field.Root, { children: /* @__PURE__ */ jsx(Input.Number, {
|
|
338
|
+
classNames: ["font-mono", classNames],
|
|
206
339
|
min: 0,
|
|
207
340
|
step: 1,
|
|
208
341
|
"aria-label": "Depth",
|
|
209
|
-
value: depth,
|
|
210
|
-
|
|
342
|
+
value: String(depth),
|
|
343
|
+
onValueChange: (_, valueAsNumber) => setDepth(Math.max(0, valueAsNumber || 0)),
|
|
211
344
|
ref: forwardedRef
|
|
212
345
|
}) });
|
|
213
346
|
});
|
|
214
347
|
SyntaxDepth.displayName = SYNTAX_DEPTH_NAME;
|
|
215
348
|
var SYNTAX_VIEWPORT_NAME = "Syntax.Viewport";
|
|
216
349
|
/** Optional scroll wrapper. Compose around `Syntax.Code` to make it scrollable. */
|
|
217
|
-
var SyntaxViewport = composable(({ children, ...props }, forwardedRef) => {
|
|
350
|
+
var SyntaxViewport = Util.composable(({ children, ...props }, forwardedRef) => {
|
|
218
351
|
return /* @__PURE__ */ jsx(ScrollArea.Root, {
|
|
219
|
-
...composableProps(props),
|
|
352
|
+
...Util.composableProps(props),
|
|
220
353
|
orientation: "all",
|
|
221
|
-
thin: true,
|
|
222
354
|
ref: forwardedRef,
|
|
223
355
|
children: /* @__PURE__ */ jsx(ScrollArea.Viewport, { children })
|
|
224
356
|
});
|
|
225
357
|
});
|
|
226
358
|
SyntaxViewport.displayName = SYNTAX_VIEWPORT_NAME;
|
|
227
359
|
var SYNTAX_CODE_NAME = "Syntax.Code";
|
|
228
|
-
/** Highlighted code leaf. Reads source/data from `Syntax.Root
|
|
229
|
-
var SyntaxCode = composable(({
|
|
230
|
-
const
|
|
231
|
-
const
|
|
360
|
+
/** Highlighted code leaf, unscrolled: `Syntax.Viewport` owns the scrolling. Reads source/data from `Syntax.Root`. */
|
|
361
|
+
var SyntaxCode = Util.composable(({ testId, ...props }, forwardedRef) => {
|
|
362
|
+
const merged = Util.composableProps(props, { classNames: "text-sm" });
|
|
363
|
+
const context = useSyntaxContext(SYNTAX_CODE_NAME);
|
|
232
364
|
if (context.mode === "json") return /* @__PURE__ */ jsx(JsonHighlighter, {
|
|
233
365
|
...merged,
|
|
366
|
+
scroll: false,
|
|
234
367
|
data: context.filteredData,
|
|
235
368
|
replacer: context.replacer,
|
|
236
369
|
testId,
|
|
@@ -238,6 +371,7 @@ var SyntaxCode = composable(({ __scopeSyntax, testId, ...props }, forwardedRef)
|
|
|
238
371
|
});
|
|
239
372
|
return /* @__PURE__ */ jsx(SyntaxHighlighter, {
|
|
240
373
|
...merged,
|
|
374
|
+
scroll: false,
|
|
241
375
|
language: context.language,
|
|
242
376
|
"data-testid": testId,
|
|
243
377
|
ref: forwardedRef,
|
|
@@ -254,6 +388,6 @@ var Syntax = {
|
|
|
254
388
|
Code: SyntaxCode
|
|
255
389
|
};
|
|
256
390
|
//#endregion
|
|
257
|
-
export { JsonHighlighter, Syntax, SyntaxHighlighter, createElement
|
|
391
|
+
export { JsonHighlighter, Syntax, SyntaxHighlighter, createElement };
|
|
258
392
|
|
|
259
393
|
//# sourceMappingURL=index.mjs.map
|
package/dist/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/SyntaxHighlighter/SyntaxHighlighter.tsx","../../src/JsonHighlighter/JsonHighlighter.tsx","../../src/Syntax/SyntaxContext.ts","../../src/Syntax/Syntax.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { Children } from 'react';\nimport { type SyntaxHighlighterProps as NaturalSyntaxHighlighterProps } from 'react-syntax-highlighter';\nimport NativeSyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-async-light';\nimport { coldarkDark as dark, coldarkCold as light } from 'react-syntax-highlighter/dist/esm/styles/prism';\n\nimport { Clipboard, composable, composableProps, useThemeContext } from '@dxos/react-ui';\nimport { mx } from '@dxos/ui-theme';\n\nconst zeroWidthSpace = '\\u200b';\n\nconst languages = {\n js: 'javascript',\n ts: 'typescript',\n};\n\nexport type SyntaxHighlighterProps = Pick<\n NaturalSyntaxHighlighterProps,\n | 'language'\n | 'renderer'\n | 'showLineNumbers'\n | 'showInlineLineNumbers'\n | 'startingLineNumber'\n | 'wrapLines'\n | 'wrapLongLines'\n | 'PreTag'\n> & {\n themeStyle?: NaturalSyntaxHighlighterProps['style'];\n fallback?: string;\n copyButton?: boolean;\n};\n\n/**\n * Inline, non-scrolling wrapper around `react-syntax-highlighter`.\n *\n * Use directly for small snippets (e.g. inside markdown code blocks).\n * For scrollable panels, compose with `Syntax.Viewport`.\n *\n * NOTE: Using `light-async` version directly from dist to avoid any chance of the heavy one being loaded.\n * The lightweight version will load specific language parsers asynchronously.\n *\n * https://github.com/react-syntax-highlighter/react-syntax-highlighter\n * https://react-syntax-highlighter.github.io/react-syntax-highlighter/demo/prism.html\n */\nexport const SyntaxHighlighter = composable<HTMLDivElement, SyntaxHighlighterProps>(\n (\n {\n classNames,\n className,\n children,\n role,\n style,\n themeStyle,\n language = 'text',\n fallback = zeroWidthSpace,\n copyButton,\n ...nativeProps\n },\n forwardedRef,\n ) => {\n const { themeMode } = useThemeContext();\n const source = Children.toArray(children).join('') || fallback;\n\n const hasCustomTheme = themeStyle && typeof themeStyle === 'object' && Object.keys(themeStyle).length > 0;\n const prismTheme = hasCustomTheme ? themeStyle : themeMode === 'dark' ? dark : light;\n\n return (\n <div\n {...composableProps(\n { classNames, className, role, style },\n {\n role: 'none',\n classNames: mx('dx-expander p-1 overflow-auto', copyButton && 'relative group'),\n },\n )}\n ref={forwardedRef}\n >\n <NativeSyntaxHighlighter\n language={languages[language as keyof typeof languages] || language}\n style={prismTheme}\n customStyle={{\n background: 'unset',\n border: 'none',\n boxShadow: 'none',\n padding: 0,\n margin: 0,\n // Non-scrolling wrapper: defer all scrolling to an enclosing `Syntax.Viewport`.\n // The prism theme sets `overflow: auto` on the <pre>, which otherwise creates a\n // nested native horizontal scrollbar alongside the viewport's custom one.\n overflow: 'visible',\n }}\n {...nativeProps}\n >\n {/* Non-empty fallback prevents collapse. */}\n {source}\n </NativeSyntaxHighlighter>\n\n {copyButton && (\n <div className='pointer-events-none absolute top-1 right-1 z-10 opacity-0 group-hover:opacity-100 focus-within:opacity-100'>\n <Clipboard.Provider>\n <Clipboard.IconButton\n value={source}\n variant='ghost'\n size={4}\n classNames='pointer-events-auto aspect-square rounded-sm'\n />\n </Clipboard.Provider>\n </div>\n )}\n </div>\n );\n },\n);\n\nSyntaxHighlighter.displayName = 'SyntaxHighlighter';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport { composable } from '@dxos/react-ui';\nimport { type CreateReplacerProps, createReplacer, safeStringify } from '@dxos/util';\n\nimport { SyntaxHighlighter, type SyntaxHighlighterProps } from '../SyntaxHighlighter';\n\nexport type JsonReplacer = CreateReplacerProps | ((key: string, value: any) => any);\n\nexport type JsonHighlighterProps = Omit<SyntaxHighlighterProps, 'children' | 'language'> & {\n data?: any;\n replacer?: JsonReplacer;\n /** Indentation passed to `JSON.stringify`. Default: `2` (pretty-printed). Pass `0` for single-line output. */\n indent?: number;\n testId?: string;\n};\n\nconst resolveReplacer = (replacer?: JsonReplacer) => {\n if (!replacer) {\n return undefined;\n }\n return typeof replacer === 'function' ? replacer : createReplacer(replacer);\n};\n\n/**\n * Inline, non-scrolling JSON renderer.\n *\n * Thin wrapper around `SyntaxHighlighter` that stringifies `data` with an optional replacer.\n * `replacer` accepts either `CreateReplacerProps` (declarative truncation) or a raw\n * `JSON.stringify`-compatible function (for bespoke serialization).\n * For filtering and scroll behaviour, compose with the `Syntax.*` namespace.\n */\nexport const JsonHighlighter = composable<HTMLDivElement, JsonHighlighterProps>(\n ({ data, replacer, indent = 2, testId, ...props }, forwardedRef) => {\n return (\n <SyntaxHighlighter {...props} language='json' data-testid={testId} ref={forwardedRef}>\n {safeStringify(data, resolveReplacer(replacer), indent)}\n </SyntaxHighlighter>\n );\n },\n);\n\nJsonHighlighter.displayName = 'JsonHighlighter';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { type Scope, createContextScope } from '@radix-ui/react-context';\n\nimport { type SyntaxContextValue } from './Syntax';\n\n// Kept out of `Syntax.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a context and its hook exported beside them force a full page reload on every edit.\n\nexport const SYNTAX_NAME = 'Syntax';\n\nexport type SyntaxScopedProps<P> = P & { __scopeSyntax?: Scope };\n\nexport const [createSyntaxContext, createSyntaxScope] = createContextScope(SYNTAX_NAME);\nexport const [SyntaxProvider, useSyntaxContext] = createSyntaxContext<SyntaxContextValue>(SYNTAX_NAME);\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { JSONPath } from 'jsonpath-plus';\nimport React, { type PropsWithChildren, forwardRef, useCallback, useMemo, useState } from 'react';\n\nimport { Input, ScrollArea } from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { type ComposableProps } from '@dxos/ui-types';\n\nimport { JsonHighlighter, type JsonReplacer } from '../JsonHighlighter';\nimport { SyntaxHighlighter } from '../SyntaxHighlighter';\nimport { SyntaxProvider, type SyntaxScopedProps, useSyntaxContext } from './SyntaxContext';\n\n//\n// Context\n//\n\nexport type SyntaxContextValue = {\n mode: 'text' | 'json';\n // Text mode.\n source?: string;\n language?: string;\n // JSON mode.\n data?: any;\n filteredData?: any;\n filterText: string;\n setFilterText: (text: string) => void;\n filterError: Error | null;\n replacer?: JsonReplacer;\n // Expansion depth (JSON mode); consumed by a `getReplacer` factory, edited via `Syntax.Depth`.\n depth: number;\n setDepth: (depth: number) => void;\n};\n\n//\n// Root\n//\n\nconst SYNTAX_ROOT_NAME = 'Syntax.Root';\n\ntype SyntaxRootProps = PropsWithChildren<{\n // Text mode.\n language?: string;\n source?: string;\n // JSON mode (presence of the `data` prop selects JSON mode; `undefined` is still JSON).\n data?: any;\n /**\n * `JSON.stringify` replacer applied to `data`. Use the function form to follow domain\n * references (e.g. ECHO refs) by returning a transformed value at the root call. Keeps\n * this package free of any domain-specific knowledge.\n */\n replacer?: JsonReplacer;\n /**\n * Depth-parametrized replacer, re-evaluated as the `Syntax.Depth` control changes. Takes\n * precedence over `replacer`. The consumer owns any domain knowledge (e.g. how depth maps to\n * ref resolution), so this package stays domain-free.\n */\n getReplacer?: (depth: number) => JsonReplacer | undefined;\n /** Initial expansion depth for `Syntax.Depth` / `getReplacer`. */\n defaultDepth?: number;\n /** Notified when the depth changes (via `Syntax.Depth`). */\n onDepthChange?: (depth: number) => void;\n}>;\n\n/**\n * Headless context provider. Selects JSON mode when the `data` prop is passed at all — even\n * `data={undefined}` — so loading states render an empty JSON view rather than flipping to\n * text mode (which would trip `Syntax.Filter`'s JSON-only guard). Mode is chosen by prop\n * presence, not value.\n */\nconst SyntaxRoot = (props: SyntaxScopedProps<SyntaxRootProps>) => {\n const { __scopeSyntax, children, language, source, replacer, getReplacer, defaultDepth = 0, onDepthChange } = props;\n const isJson = 'data' in props;\n const data = props.data;\n const [filterText, setFilterText] = useState('');\n const [depth, setDepthState] = useState(defaultDepth);\n const setDepth = useCallback(\n (next: number) => {\n setDepthState(next);\n onDepthChange?.(next);\n },\n [onDepthChange],\n );\n\n // `getReplacer` (depth-parametrized) takes precedence over the static `replacer`.\n const effectiveReplacer = useMemo(\n () => (getReplacer ? getReplacer(depth) : replacer),\n [getReplacer, replacer, depth],\n );\n\n const { filteredData, filterError } = useMemo<{ filteredData: any; filterError: Error | null }>(() => {\n if (!isJson || !filterText.trim().length) {\n return { filteredData: data, filterError: null };\n }\n try {\n return { filteredData: JSONPath({ path: filterText, json: data }), filterError: null };\n } catch (err) {\n return { filteredData: data, filterError: err as Error };\n }\n }, [isJson, data, filterText]);\n\n return (\n <SyntaxProvider\n scope={__scopeSyntax}\n mode={isJson ? 'json' : 'text'}\n source={source}\n language={language}\n data={data}\n filteredData={filteredData}\n filterText={filterText}\n setFilterText={setFilterText}\n filterError={filterError}\n replacer={effectiveReplacer}\n depth={depth}\n setDepth={setDepth}\n >\n {children}\n </SyntaxProvider>\n );\n};\n\nSyntaxRoot.displayName = SYNTAX_ROOT_NAME;\n\n//\n// Content\n//\n\nconst SYNTAX_CONTENT_NAME = 'Syntax.Content';\n\ntype SyntaxContentProps = ComposableProps;\n\n/** Flex-column layout container for composite parts. */\nconst SyntaxContent = composable<HTMLDivElement, SyntaxContentProps>(({ children, ...props }, forwardedRef) => {\n return (\n <div {...composableProps(props, { classNames: 'flex flex-col h-full min-h-0 overflow-hidden' })} ref={forwardedRef}>\n {children}\n </div>\n );\n});\n\nSyntaxContent.displayName = SYNTAX_CONTENT_NAME;\n\n//\n// Filter\n//\n\nconst SYNTAX_FILTER_NAME = 'Syntax.Filter';\n\ntype SyntaxFilterProps = ComposableProps<{\n placeholder?: string;\n}>;\n\n/** JSONPath filter input. Only meaningful when `Syntax.Root` is in JSON mode. */\nconst SyntaxFilter = forwardRef<HTMLInputElement, SyntaxScopedProps<SyntaxFilterProps>>(\n ({ __scopeSyntax, classNames, placeholder = 'JSONPath (e.g., $.graph.nodes)' }, forwardedRef) => {\n const { mode, filterText, setFilterText, filterError } = useSyntaxContext(SYNTAX_FILTER_NAME, __scopeSyntax);\n if (mode !== 'json') {\n throw new Error(`\\`${SYNTAX_FILTER_NAME}\\` requires \\`Syntax.Root\\` to be in JSON mode (pass \\`data\\`).`);\n }\n\n return (\n <Input.Root validationValence={filterError ? 'error' : 'success'}>\n <Input.TextInput\n classNames={['p-1 px-2 font-mono', filterError && 'border-rose-500', classNames]}\n variant='subdued'\n value={filterText}\n placeholder={placeholder}\n onChange={(event) => setFilterText(event.target.value)}\n ref={forwardedRef}\n />\n </Input.Root>\n );\n },\n);\n\nSyntaxFilter.displayName = SYNTAX_FILTER_NAME;\n\n//\n// Depth\n//\n\nconst SYNTAX_DEPTH_NAME = 'Syntax.Depth';\n\ntype SyntaxDepthProps = ComposableProps;\n\n/**\n * Numeric expansion-depth control bound to `Syntax.Root`'s depth state. Meaningful when the Root is\n * given a `getReplacer` that consumes depth (e.g. to resolve references N levels deep).\n */\nconst SyntaxDepth = forwardRef<HTMLInputElement, SyntaxScopedProps<SyntaxDepthProps>>(\n ({ __scopeSyntax, classNames }, forwardedRef) => {\n const { depth, setDepth } = useSyntaxContext(SYNTAX_DEPTH_NAME, __scopeSyntax);\n return (\n <Input.Root>\n <Input.TextInput\n classNames={['p-1 px-2 font-mono', classNames]}\n variant='subdued'\n type='number'\n min={0}\n step={1}\n aria-label='Depth'\n value={depth}\n onChange={(event) => setDepth(Math.max(0, Number(event.target.value) || 0))}\n ref={forwardedRef}\n />\n </Input.Root>\n );\n },\n);\n\nSyntaxDepth.displayName = SYNTAX_DEPTH_NAME;\n\n//\n// Viewport\n//\n\nconst SYNTAX_VIEWPORT_NAME = 'Syntax.Viewport';\n\ntype SyntaxViewportProps = ComposableProps;\n\n/** Optional scroll wrapper. Compose around `Syntax.Code` to make it scrollable. */\nconst SyntaxViewport = composable<HTMLDivElement, SyntaxViewportProps>(({ children, ...props }, forwardedRef) => {\n return (\n <ScrollArea.Root {...composableProps(props)} orientation='all' thin ref={forwardedRef}>\n <ScrollArea.Viewport>{children}</ScrollArea.Viewport>\n </ScrollArea.Root>\n );\n});\n\nSyntaxViewport.displayName = SYNTAX_VIEWPORT_NAME;\n\n//\n// Code\n//\n\nconst SYNTAX_CODE_NAME = 'Syntax.Code';\n\ntype SyntaxCodeProps = ComposableProps<{\n testId?: string;\n}>;\n\n/** Highlighted code leaf. Reads source/data from `Syntax.Root` context. */\nconst SyntaxCode = composable<HTMLDivElement, SyntaxScopedProps<SyntaxCodeProps>>(\n ({ __scopeSyntax, testId, ...props }, forwardedRef) => {\n const context = useSyntaxContext(SYNTAX_CODE_NAME, __scopeSyntax);\n const merged = composableProps(props, { classNames: 'py-1 px-2 text-sm' });\n\n if (context.mode === 'json') {\n return (\n <JsonHighlighter\n {...merged}\n data={context.filteredData}\n replacer={context.replacer}\n testId={testId}\n ref={forwardedRef}\n />\n );\n }\n\n return (\n <SyntaxHighlighter {...merged} language={context.language} data-testid={testId} ref={forwardedRef}>\n {context.source ?? ''}\n </SyntaxHighlighter>\n );\n },\n);\n\nSyntaxCode.displayName = SYNTAX_CODE_NAME;\n\n//\n// Syntax\n//\n\nexport const Syntax = {\n Root: SyntaxRoot,\n Content: SyntaxContent,\n Filter: SyntaxFilter,\n Depth: SyntaxDepth,\n Viewport: SyntaxViewport,\n Code: SyntaxCode,\n};\n\nexport type {\n SyntaxCodeProps,\n SyntaxContentProps,\n SyntaxDepthProps,\n SyntaxFilterProps,\n SyntaxRootProps,\n SyntaxViewportProps,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/SyntaxHighlighter/renderer.ts","../../src/SyntaxHighlighter/SyntaxHighlighter.tsx","../../src/JsonHighlighter/JsonHighlighter.tsx","../../src/Syntax/SyntaxContext.ts","../../src/Syntax/Syntax.tsx"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\nimport { type CSSProperties, type ReactNode, createElement } from 'react';\nimport { type SyntaxHighlighterProps } from 'react-syntax-highlighter';\n\ntype Renderer = NonNullable<SyntaxHighlighterProps['renderer']>;\ntype RendererProps = Parameters<Renderer>[0];\ntype Stylesheet = RendererProps['stylesheet'];\ntype RenderNode = RendererProps['rows'][number];\n\ntype StylesheetIndex = {\n /** Every class name any selector in the stylesheet mentions. */\n selectors: Set<string>;\n /** Merged stylesheet entries, keyed by a node's joined class names. */\n styles: Map<string, CSSProperties>;\n};\n\nconst indexes = new WeakMap<Stylesheet, StylesheetIndex>();\n\nconst indexOf = (stylesheet: Stylesheet): StylesheetIndex => {\n let index = indexes.get(stylesheet);\n if (!index) {\n const selectors = new Set<string>();\n for (const selector of Object.keys(stylesheet)) {\n for (const className of selector.split('.')) {\n selectors.add(className);\n }\n }\n index = { selectors, styles: new Map() };\n indexes.set(stylesheet, index);\n }\n\n return index;\n};\n\n/**\n * Every ordered selection of one to four class names, shortest first — the selector keys a\n * compound class list can match, in the precedence order `react-syntax-highlighter` applies them.\n */\nconst classNameCombinations = (classNames: string[]): string[] => {\n const pool = classNames.slice(0, 4);\n const combinations: string[] = [];\n const extend = (prefix: string[], remaining: number[], size: number) => {\n if (prefix.length === size) {\n combinations.push(prefix.join('.'));\n return;\n }\n for (const position of remaining) {\n extend(\n [...prefix, pool[position]],\n remaining.filter((other) => other !== position),\n size,\n );\n }\n };\n const positions = pool.map((_, position) => position);\n for (let size = 1; size <= pool.length; size++) {\n extend([], positions, size);\n }\n\n return combinations;\n};\n\nconst styleOf = (index: StylesheetIndex, stylesheet: Stylesheet, classNames: string[]): CSSProperties => {\n const key = classNames.join(' ');\n let style = index.styles.get(key);\n if (!style) {\n style = {};\n for (const selector of classNameCombinations(classNames.filter((className) => className !== 'token'))) {\n Object.assign(style, stylesheet[selector]);\n }\n index.styles.set(key, style);\n }\n\n return style;\n};\n\nconst renderNode = (node: RenderNode, stylesheet: Stylesheet, useInlineStyles: boolean, key: string): ReactNode => {\n if (node.type === 'text') {\n return node.value;\n }\n if (!node.tagName) {\n return undefined;\n }\n\n const properties = node.properties ?? { className: [] };\n const classNames: string[] = properties.className ?? [];\n let props: Record<string, unknown>;\n if (!useInlineStyles) {\n props = { ...properties, className: classNames.join(' ') };\n } else {\n const index = indexOf(stylesheet);\n const className = [\n ...(classNames.includes('token') ? ['token'] : []),\n ...classNames.filter((name) => !index.selectors.has(name)),\n ].join(' ');\n props = {\n ...properties,\n className: className || undefined,\n style: { ...properties.style, ...styleOf(index, stylesheet, classNames) },\n };\n }\n\n const children = (node.children ?? []).map((child, position) =>\n renderNode(child, stylesheet, useInlineStyles, `code-segment-1-${position}`),\n );\n return createElement(node.tagName, { key, ...props }, children);\n};\n\n/**\n * Drop-in for `react-syntax-highlighter`'s default row renderer, producing the same elements.\n * The stock renderer rebuilds the stylesheet's full selector list (a quadratic scan) for every\n * token node, which dominated the main thread whenever a highlighted block re-rendered.\n */\nexport const renderRows: Renderer = ({ rows, stylesheet, useInlineStyles }) =>\n rows.map((row, position) => renderNode(row, stylesheet, useInlineStyles, `code-segment-${position}`));\n","//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { Children, type ReactNode, memo } from 'react';\nimport { type SyntaxHighlighterProps as NaturalSyntaxHighlighterProps } from 'react-syntax-highlighter';\nimport NativeSyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-async-light';\nimport { coldarkDark as dark, coldarkCold as light } from 'react-syntax-highlighter/dist/esm/styles/prism';\n\nimport * as Hooks from '@dxos/react-ui/Hooks';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as SystemButton from '@dxos/react-ui/SystemButton';\nimport * as Util from '@dxos/react-ui/Util';\nimport { mx } from '@dxos/ui-theme';\nimport { type AllowedAxis } from '@dxos/ui-types';\n\nimport { renderRows } from './renderer.ts';\n\nconst zeroWidthSpace = '\\u200b';\n\nconst languages = {\n js: 'javascript',\n ts: 'typescript',\n};\n\n/**\n * Above this, source is rendered unhighlighted. react-syntax-highlighter splices every line into a\n * single token array and wraps every token in an inline-styled element, so tokenizing grows\n * super-linearly in one synchronous render — a 3 MB payload takes about 30 s, and past roughly 123k\n * lines it throws. Plain text skips the tokenizer and keeps this component's own `pre`/`code` styles.\n */\nconst MAX_HIGHLIGHTED_LENGTH = 20_000;\n\nexport type SyntaxHighlighterProps = Pick<\n NaturalSyntaxHighlighterProps,\n | 'language'\n | 'renderer'\n | 'showLineNumbers'\n | 'showInlineLineNumbers'\n | 'startingLineNumber'\n | 'wrapLines'\n | 'wrapLongLines'\n | 'PreTag'\n> & {\n themeStyle?: NaturalSyntaxHighlighterProps['style'];\n fallback?: string;\n copyButton?: boolean;\n /**\n * The axes the built-in `ScrollArea` scrolls on (default: all). `false` renders the bare,\n * non-scrolling leaf for composition inside `Syntax.Viewport`.\n */\n scroll?: AllowedAxis | false;\n};\n\n/**\n * Highlighted source inside the family's themed `ScrollArea`, so a long line scrolls with the thin\n * scrollbar rather than the platform's. Pass `scroll={false}` to get the bare leaf.\n *\n * NOTE: Using `light-async` version directly from dist to avoid any chance of the heavy one being loaded.\n * The lightweight version will load specific language parsers asynchronously.\n *\n * https://github.com/react-syntax-highlighter/react-syntax-highlighter\n * https://react-syntax-highlighter.github.io/react-syntax-highlighter/demo/prism.html\n */\nexport const SyntaxHighlighter = Util.composable<HTMLDivElement, SyntaxHighlighterProps>(\n ({ scroll = 'all', copyButton, classNames, className, role, style, ...props }, forwardedRef) => {\n if (scroll === false) {\n return (\n <SyntaxHighlighterLeaf\n {...props}\n {...{ classNames, className, role, style }}\n copyButton={copyButton}\n ref={forwardedRef}\n />\n );\n }\n\n // The copy button sits on the scroll root so it stays put while the source scrolls under it.\n const source = sourceOf(props.children, props.fallback);\n return (\n <ScrollArea.Root\n role={role ?? 'none'}\n style={style}\n classNames={[className, classNames, copyButton && 'relative group']}\n orientation={scroll}\n ref={forwardedRef}\n >\n <ScrollArea.Viewport>\n <SyntaxHighlighterLeaf {...props} />\n </ScrollArea.Viewport>\n {copyButton && <CopyOverlay source={source} />}\n </ScrollArea.Root>\n );\n },\n);\n\nSyntaxHighlighter.displayName = 'SyntaxHighlighter';\n\nconst sourceOf = (children: ReactNode, fallback = zeroWidthSpace): string =>\n Children.toArray(children).join('') || fallback;\n\nconst CopyOverlay = ({ source }: { source: string }) => (\n <div className='pointer-events-none absolute top-1 right-1 z-10 opacity-0 group-hover:opacity-100 focus-within:opacity-100'>\n <SystemButton.Clipboard\n iconOnly\n value={source}\n variant='ghost'\n iconSize='md'\n classNames='pointer-events-auto aspect-square rounded-sm'\n />\n </div>\n);\n\n/** The non-scrolling leaf: all scrolling is deferred to an enclosing viewport. */\nconst SyntaxHighlighterLeaf = Util.composable<HTMLDivElement, Omit<SyntaxHighlighterProps, 'scroll'>>(\n (\n {\n classNames,\n className,\n children,\n role,\n style,\n themeStyle,\n language: languageProp = 'text',\n fallback = zeroWidthSpace,\n copyButton,\n ...nativeProps\n },\n forwardedRef,\n ) => {\n const themeMode = Hooks.useThemeMode();\n const source = sourceOf(children, fallback);\n const language = source.length > MAX_HIGHLIGHTED_LENGTH ? 'text' : languageProp;\n\n const hasCustomTheme = themeStyle && typeof themeStyle === 'object' && Object.keys(themeStyle).length > 0;\n const prismTheme = hasCustomTheme ? themeStyle : themeMode === 'dark' ? dark : light;\n\n return (\n <div\n {...Util.composableProps(\n { classNames, className, role, style },\n {\n role: 'none',\n classNames: mx('dx-expand overflow-visible p-1', copyButton && 'relative group'),\n },\n )}\n ref={forwardedRef}\n >\n <HighlightedSource\n language={languages[language as keyof typeof languages] || language}\n style={prismTheme}\n {...nativeProps}\n >\n {source}\n </HighlightedSource>\n\n {copyButton && <CopyOverlay source={source} />}\n </div>\n );\n },\n);\n\nSyntaxHighlighterLeaf.displayName = 'SyntaxHighlighterLeaf';\n\nconst customStyle: NaturalSyntaxHighlighterProps['customStyle'] = {\n background: 'unset',\n border: 'none',\n boxShadow: 'none',\n padding: 0,\n margin: 0,\n // This allows setting max-h-[6lh] on the Syntax.Code component.\n lineHeight: 'inherit',\n // Non-scrolling wrapper: defer all scrolling to an enclosing `Syntax.Viewport`.\n // The prism theme sets `overflow: auto` on the <pre>, which otherwise creates a\n // nested native horizontal scrollbar alongside the viewport's custom one.\n overflow: 'visible',\n};\n\nconst codeTagProps: NaturalSyntaxHighlighterProps['codeTagProps'] = {\n style: {\n lineHeight: 'inherit',\n // `block`, not the default `inline`: as an inline box every line is the union of the\n // <pre>'s strut and this element's own box, and the two carry different font stacks\n // (the prism theme's vs the app's), so lines advanced 16.5px under a 16px\n // line-height — enough that a `max-h-[Nlh]` cap showed N-1 lines and a sliver.\n display: 'block',\n },\n};\n\ntype HighlightedSourceProps = Omit<SyntaxHighlighterProps, 'themeStyle' | 'fallback' | 'copyButton' | 'scroll'> & {\n style: NaturalSyntaxHighlighterProps['style'];\n children: string;\n};\n\n/**\n * Memoized on primitive props because tokenizing and building the element tree is the expensive\n * part, and streaming parents (e.g. the assistant's tool panel) re-render with unchanged source.\n */\nconst HighlightedSource = memo(({ children, renderer, wrapLines, ...props }: HighlightedSourceProps) => (\n <NativeSyntaxHighlighter\n customStyle={customStyle}\n // Copied per render: the library writes `whiteSpace` into this style, which would leak across instances.\n codeTagProps={{ ...codeTagProps, style: { ...codeTagProps?.style } }}\n renderer={renderer ?? renderRows}\n // Any renderer makes the library default `wrapLines` to true; only a caller's own renderer should get that.\n wrapLines={wrapLines ?? (renderer ? undefined : false)}\n {...props}\n >\n {/* Non-empty fallback prevents collapse. */}\n {children}\n </NativeSyntaxHighlighter>\n));\n\nHighlightedSource.displayName = 'HighlightedSource';\n\nSyntaxHighlighter.displayName = 'SyntaxHighlighter';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport React from 'react';\n\nimport * as Util from '@dxos/react-ui/Util';\nimport { type CreateReplacerProps, createReplacer, safeStringify } from '@dxos/util';\n\nimport { SyntaxHighlighter, type SyntaxHighlighterProps } from '../SyntaxHighlighter/index.ts';\n\nexport type JsonReplacer = CreateReplacerProps | ((key: string, value: any) => any);\n\nexport type JsonHighlighterProps = Omit<SyntaxHighlighterProps, 'children' | 'language'> & {\n data?: any;\n replacer?: JsonReplacer;\n /** Indentation passed to `JSON.stringify`. Default: `2` (pretty-printed). Pass `0` for single-line output. */\n indent?: number;\n testId?: string;\n};\n\nconst resolveReplacer = (replacer?: JsonReplacer) => {\n if (!replacer) {\n return undefined;\n }\n\n return typeof replacer === 'function' ? replacer : createReplacer(replacer);\n};\n\n/**\n * JSON in the family's themed `ScrollArea`: the shorthand for showing a value.\n *\n * Thin wrapper around `SyntaxHighlighter` that stringifies `data` with an optional replacer.\n * `replacer` accepts either `CreateReplacerProps` (declarative truncation) or a raw\n * `JSON.stringify`-compatible function (for bespoke serialization). `scroll` picks the axes\n * (default: all). Compose with the `Syntax.*` namespace only for filtering or a depth control.\n */\nexport const JsonHighlighter = Util.composable<HTMLDivElement, JsonHighlighterProps>(\n ({ data, replacer, indent = 2, testId, ...props }, forwardedRef) => {\n return (\n <SyntaxHighlighter {...props} language='json' data-testid={testId} ref={forwardedRef}>\n {safeStringify(data, resolveReplacer(replacer), indent)}\n </SyntaxHighlighter>\n );\n },\n);\n\nJsonHighlighter.displayName = 'JsonHighlighter';\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { createContext } from '@dxos/react-hooks';\n\nimport { type SyntaxContextValue } from './Syntax.tsx';\n\n// Kept out of `Syntax.tsx`: react-refresh only fast-refreshes a module whose exports are all\n// components, so a context and its hook exported beside them force a full page reload on every edit.\n\nexport const SYNTAX_NAME = 'Syntax';\n\nexport const [SyntaxProvider, useSyntaxContext] = createContext<SyntaxContextValue>(SYNTAX_NAME);\n","//\n// Copyright 2025 DXOS.org\n//\n\nimport { JSONPath } from 'jsonpath-plus';\nimport React, { type PropsWithChildren, forwardRef, useCallback, useMemo, useState } from 'react';\n\nimport * as Field from '@dxos/react-ui/Field';\nimport * as Input from '@dxos/react-ui/Input';\nimport * as ScrollArea from '@dxos/react-ui/ScrollArea';\nimport * as Util from '@dxos/react-ui/Util';\nimport { type ComposableProps } from '@dxos/ui-types';\n\nimport { JsonHighlighter, type JsonReplacer } from '../JsonHighlighter/index.ts';\nimport { SyntaxHighlighter } from '../SyntaxHighlighter/index.ts';\nimport { SyntaxProvider, useSyntaxContext } from './SyntaxContext.ts';\n\n//\n// Context\n//\n\nexport type SyntaxContextValue = {\n mode: 'text' | 'json';\n // Text mode.\n source?: string;\n language?: string;\n // JSON mode.\n data?: any;\n filteredData?: any;\n filterText: string;\n setFilterText: (text: string) => void;\n filterError: Error | null;\n replacer?: JsonReplacer;\n // Expansion depth (JSON mode); consumed by a `getReplacer` factory, edited via `Syntax.Depth`.\n depth: number;\n setDepth: (depth: number) => void;\n};\n\n//\n// Root\n//\n\nconst SYNTAX_ROOT_NAME = 'Syntax.Root';\n\ntype SyntaxRootProps = PropsWithChildren<{\n // Text mode.\n language?: string;\n source?: string;\n // JSON mode (presence of the `data` prop selects JSON mode; `undefined` is still JSON).\n data?: any;\n /**\n * `JSON.stringify` replacer applied to `data`. Use the function form to follow domain\n * references (e.g. ECHO refs) by returning a transformed value at the root call. Keeps\n * this package free of any domain-specific knowledge.\n */\n replacer?: JsonReplacer;\n /**\n * Depth-parametrized replacer, re-evaluated as the `Syntax.Depth` control changes. Takes\n * precedence over `replacer`. The consumer owns any domain knowledge (e.g. how depth maps to\n * ref resolution), so this package stays domain-free.\n */\n getReplacer?: (depth: number) => JsonReplacer | undefined;\n /** Initial expansion depth for `Syntax.Depth` / `getReplacer`. */\n defaultDepth?: number;\n /** Notified when the depth changes (via `Syntax.Depth`). */\n onDepthChange?: (depth: number) => void;\n}>;\n\n/**\n * Headless context provider. Selects JSON mode when the `data` prop is passed at all — even\n * `data={undefined}` — so loading states render an empty JSON view rather than flipping to\n * text mode (which would trip `Syntax.Filter`'s JSON-only guard). Mode is chosen by prop\n * presence, not value.\n */\nconst SyntaxRoot = (props: SyntaxRootProps) => {\n const { children, language, source, replacer, getReplacer, defaultDepth = 0, onDepthChange } = props;\n const isJson = 'data' in props;\n const data = props.data;\n const [filterText, setFilterText] = useState('');\n const [depth, setDepthState] = useState(defaultDepth);\n const setDepth = useCallback(\n (next: number) => {\n setDepthState(next);\n onDepthChange?.(next);\n },\n [onDepthChange],\n );\n\n // `getReplacer` (depth-parametrized) takes precedence over the static `replacer`.\n const effectiveReplacer = useMemo(\n () => (getReplacer ? getReplacer(depth) : replacer),\n [getReplacer, replacer, depth],\n );\n\n const { filteredData, filterError } = useMemo<{ filteredData: any; filterError: Error | null }>(() => {\n if (!isJson || !filterText.trim().length) {\n return { filteredData: data, filterError: null };\n }\n try {\n return { filteredData: JSONPath({ path: filterText, json: data }), filterError: null };\n } catch (err) {\n return { filteredData: data, filterError: err as Error };\n }\n }, [isJson, data, filterText]);\n\n return (\n <SyntaxProvider\n mode={isJson ? 'json' : 'text'}\n source={source}\n language={language}\n data={data}\n filteredData={filteredData}\n filterText={filterText}\n setFilterText={setFilterText}\n filterError={filterError}\n replacer={effectiveReplacer}\n depth={depth}\n setDepth={setDepth}\n >\n {children}\n </SyntaxProvider>\n );\n};\n\nSyntaxRoot.displayName = SYNTAX_ROOT_NAME;\n\n//\n// Content\n//\n\nconst SYNTAX_CONTENT_NAME = 'Syntax.Content';\n\ntype SyntaxContentProps = ComposableProps;\n\n/** Flex-column layout container for composite parts. */\nconst SyntaxContent = Util.composable<HTMLDivElement, SyntaxContentProps>(({ children, ...props }, forwardedRef) => {\n return (\n <div\n {...Util.composableProps(props, { classNames: 'flex flex-col p-1 dx-expand overflow-hidden' })}\n ref={forwardedRef}\n >\n {children}\n </div>\n );\n});\n\nSyntaxContent.displayName = SYNTAX_CONTENT_NAME;\n\n//\n// Filter\n//\n\nconst SYNTAX_FILTER_NAME = 'Syntax.Filter';\n\ntype SyntaxFilterProps = ComposableProps<{\n placeholder?: string;\n}>;\n\n/** JSONPath filter input. Only meaningful when `Syntax.Root` is in JSON mode. */\nconst SyntaxFilter = forwardRef<HTMLInputElement, SyntaxFilterProps>(\n ({ classNames, placeholder = 'JSONPath (e.g., $.graph.nodes)' }, forwardedRef) => {\n const { mode, filterText, setFilterText, filterError } = useSyntaxContext(SYNTAX_FILTER_NAME);\n if (mode !== 'json') {\n throw new Error(`\\`${SYNTAX_FILTER_NAME}\\` requires \\`Syntax.Root\\` to be in JSON mode (pass \\`data\\`).`);\n }\n\n return (\n <Field.Root validationValence={filterError ? 'error' : 'success'}>\n <Input.Root\n classNames={['p-1 px-2 font-mono', filterError && 'border-rose-500', classNames]}\n variant='subdued'\n value={filterText}\n placeholder={placeholder}\n onChange={(event) => setFilterText(event.target.value)}\n ref={forwardedRef}\n />\n </Field.Root>\n );\n },\n);\n\nSyntaxFilter.displayName = SYNTAX_FILTER_NAME;\n\n//\n// Depth\n//\n\nconst SYNTAX_DEPTH_NAME = 'Syntax.Depth';\n\ntype SyntaxDepthProps = ComposableProps;\n\n/**\n * Numeric expansion-depth control bound to `Syntax.Root`'s depth state. Meaningful when the Root is\n * given a `getReplacer` that consumes depth (e.g. to resolve references N levels deep).\n */\nconst SyntaxDepth = forwardRef<HTMLInputElement, SyntaxDepthProps>(({ classNames }, forwardedRef) => {\n const { depth, setDepth } = useSyntaxContext(SYNTAX_DEPTH_NAME);\n return (\n <Field.Root>\n <Input.Number\n classNames={['font-mono', classNames]}\n min={0}\n step={1}\n aria-label='Depth'\n value={String(depth)}\n onValueChange={(_, valueAsNumber) => setDepth(Math.max(0, valueAsNumber || 0))}\n ref={forwardedRef}\n />\n </Field.Root>\n );\n});\n\nSyntaxDepth.displayName = SYNTAX_DEPTH_NAME;\n\n//\n// Viewport\n//\n\nconst SYNTAX_VIEWPORT_NAME = 'Syntax.Viewport';\n\ntype SyntaxViewportProps = ComposableProps;\n\n/** Optional scroll wrapper. Compose around `Syntax.Code` to make it scrollable. */\nconst SyntaxViewport = Util.composable<HTMLDivElement, SyntaxViewportProps>(({ children, ...props }, forwardedRef) => {\n return (\n <ScrollArea.Root {...Util.composableProps(props)} orientation='all' ref={forwardedRef}>\n <ScrollArea.Viewport>{children}</ScrollArea.Viewport>\n </ScrollArea.Root>\n );\n});\n\nSyntaxViewport.displayName = SYNTAX_VIEWPORT_NAME;\n\n//\n// Code\n//\n\nconst SYNTAX_CODE_NAME = 'Syntax.Code';\n\ntype SyntaxCodeProps = ComposableProps<{\n testId?: string;\n}>;\n\n/** Highlighted code leaf, unscrolled: `Syntax.Viewport` owns the scrolling. Reads source/data from `Syntax.Root`. */\nconst SyntaxCode = Util.composable<HTMLDivElement, SyntaxCodeProps>(({ testId, ...props }, forwardedRef) => {\n const merged = Util.composableProps(props, { classNames: 'text-sm' });\n\n const context = useSyntaxContext(SYNTAX_CODE_NAME);\n if (context.mode === 'json') {\n return (\n <JsonHighlighter\n {...merged}\n scroll={false}\n data={context.filteredData}\n replacer={context.replacer}\n testId={testId}\n ref={forwardedRef}\n />\n );\n }\n\n return (\n <SyntaxHighlighter {...merged} scroll={false} language={context.language} data-testid={testId} ref={forwardedRef}>\n {context.source ?? ''}\n </SyntaxHighlighter>\n );\n});\n\nSyntaxCode.displayName = SYNTAX_CODE_NAME;\n\n//\n// Syntax\n//\n\nexport const Syntax = {\n Root: SyntaxRoot,\n Content: SyntaxContent,\n Filter: SyntaxFilter,\n Depth: SyntaxDepth,\n Viewport: SyntaxViewport,\n Code: SyntaxCode,\n};\n\nexport type {\n SyntaxCodeProps,\n SyntaxContentProps,\n SyntaxDepthProps,\n SyntaxFilterProps,\n SyntaxRootProps,\n SyntaxViewportProps,\n};\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type CreateReplacerProps } from '@dxos/util';
|
|
3
|
-
import { type SyntaxHighlighterProps } from '../SyntaxHighlighter';
|
|
3
|
+
import { type SyntaxHighlighterProps } from '../SyntaxHighlighter/index.ts';
|
|
4
4
|
export type JsonReplacer = CreateReplacerProps | ((key: string, value: any) => any);
|
|
5
5
|
export type JsonHighlighterProps = Omit<SyntaxHighlighterProps, 'children' | 'language'> & {
|
|
6
6
|
data?: any;
|
|
@@ -10,12 +10,12 @@ export type JsonHighlighterProps = Omit<SyntaxHighlighterProps, 'children' | 'la
|
|
|
10
10
|
testId?: string;
|
|
11
11
|
};
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* JSON in the family's themed `ScrollArea`: the shorthand for showing a value.
|
|
14
14
|
*
|
|
15
15
|
* Thin wrapper around `SyntaxHighlighter` that stringifies `data` with an optional replacer.
|
|
16
16
|
* `replacer` accepts either `CreateReplacerProps` (declarative truncation) or a raw
|
|
17
|
-
* `JSON.stringify`-compatible function (for bespoke serialization).
|
|
18
|
-
*
|
|
17
|
+
* `JSON.stringify`-compatible function (for bespoke serialization). `scroll` picks the axes
|
|
18
|
+
* (default: all). Compose with the `Syntax.*` namespace only for filtering or a depth control.
|
|
19
19
|
*/
|
|
20
20
|
export declare const JsonHighlighter: React.ForwardRefExoticComponent<Omit<JsonHighlighterProps, "className"> & {
|
|
21
21
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonHighlighter.d.ts","sourceRoot":"","sources":["../../../../src/JsonHighlighter/JsonHighlighter.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,KAAK,mBAAmB,EAAiC,MAAM,YAAY,CAAC;AAErF,OAAO,EAAqB,KAAK,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"JsonHighlighter.d.ts","sourceRoot":"","sources":["../../../../src/JsonHighlighter/JsonHighlighter.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,KAAK,mBAAmB,EAAiC,MAAM,YAAY,CAAC;AAErF,OAAO,EAAqB,KAAK,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAE/F,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;AAEpF,MAAM,MAAM,oBAAoB,GAAG,IAAI,CAAC,sBAAsB,EAAE,UAAU,GAAG,UAAU,CAAC,GAAG;IACzF,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,8GAA8G;IAC9G,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAUF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;6GAQ3B,CAAC"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type StoryObj } from '@storybook/react-vite';
|
|
2
|
-
import { JsonHighlighter } from './JsonHighlighter';
|
|
2
|
+
import { JsonHighlighter } from './JsonHighlighter.tsx';
|
|
3
3
|
declare const meta: {
|
|
4
4
|
title: string;
|
|
5
|
-
component: import("react").ForwardRefExoticComponent<Omit<import("./JsonHighlighter").JsonHighlighterProps, "className"> & {
|
|
5
|
+
component: import("react").ForwardRefExoticComponent<Omit<import("./JsonHighlighter.tsx").JsonHighlighterProps, "className"> & {
|
|
6
6
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
7
7
|
} & Pick<import("react").HTMLAttributes<Element>, "children" | "role" | "style"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
8
8
|
decorators: import("@storybook/react").Decorator[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsonHighlighter.stories.d.ts","sourceRoot":"","sources":["../../../../src/JsonHighlighter/JsonHighlighter.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKjE,OAAO,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"JsonHighlighter.stories.d.ts","sourceRoot":"","sources":["../../../../src/JsonHighlighter/JsonHighlighter.stories.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAa,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAKjE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAmCxD,QAAA,MAAM,IAAI;;;;;;CAI8B,CAAC;eAE1B,IAAI;AAEnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,eAAe,CAAC,CAAC;AAE9C,eAAO,MAAM,OAAO,EAAE,KAIrB,CAAC;AAEF,eAAO,MAAM,KAAK,EAAE,KAInB,CAAC"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './JsonHighlighter';
|
|
1
|
+
export * from './JsonHighlighter.tsx';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/JsonHighlighter/index.ts"],"names":[],"mappings":"AAIA,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/JsonHighlighter/index.ts"],"names":[],"mappings":"AAIA,cAAc,uBAAuB,CAAC"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import React, { type PropsWithChildren } from 'react';
|
|
2
2
|
import { type ComposableProps } from '@dxos/ui-types';
|
|
3
|
-
import { type JsonReplacer } from '../JsonHighlighter';
|
|
4
|
-
import { type SyntaxScopedProps } from './SyntaxContext';
|
|
3
|
+
import { type JsonReplacer } from '../JsonHighlighter/index.ts';
|
|
5
4
|
export type SyntaxContextValue = {
|
|
6
5
|
mode: 'text' | 'json';
|
|
7
6
|
source?: string;
|
|
@@ -43,7 +42,7 @@ type SyntaxRootProps = PropsWithChildren<{
|
|
|
43
42
|
* presence, not value.
|
|
44
43
|
*/
|
|
45
44
|
declare const SyntaxRoot: {
|
|
46
|
-
(props:
|
|
45
|
+
(props: SyntaxRootProps): React.JSX.Element;
|
|
47
46
|
displayName: string;
|
|
48
47
|
};
|
|
49
48
|
type SyntaxContentProps = ComposableProps;
|
|
@@ -64,18 +63,14 @@ export declare const Syntax: {
|
|
|
64
63
|
placeholder?: string;
|
|
65
64
|
}, "className"> & {
|
|
66
65
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
67
|
-
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> &
|
|
68
|
-
__scopeSyntax?: import("@radix-ui/react-context").Scope;
|
|
69
|
-
} & React.RefAttributes<HTMLInputElement>>;
|
|
66
|
+
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> & React.RefAttributes<HTMLInputElement>>;
|
|
70
67
|
Depth: React.ForwardRefExoticComponent<Omit<{}, "className"> & {
|
|
71
68
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
72
|
-
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> &
|
|
73
|
-
__scopeSyntax?: import("@radix-ui/react-context").Scope;
|
|
74
|
-
} & React.RefAttributes<HTMLInputElement>>;
|
|
69
|
+
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> & React.RefAttributes<HTMLInputElement>>;
|
|
75
70
|
Viewport: React.ForwardRefExoticComponent<Omit<SyntaxViewportProps, "className"> & {
|
|
76
71
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
77
72
|
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> & React.RefAttributes<HTMLDivElement>>;
|
|
78
|
-
Code: React.ForwardRefExoticComponent<Omit<
|
|
73
|
+
Code: React.ForwardRefExoticComponent<Omit<SyntaxCodeProps, "className"> & {
|
|
79
74
|
classNames?: import("@dxos/ui-types").ClassNameValue;
|
|
80
75
|
} & Pick<React.HTMLAttributes<Element>, "children" | "role" | "style"> & React.RefAttributes<HTMLDivElement>>;
|
|
81
76
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Syntax.d.ts","sourceRoot":"","sources":["../../../../src/Syntax/Syntax.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAA8C,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Syntax.d.ts","sourceRoot":"","sources":["../../../../src/Syntax/Syntax.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,EAAE,KAAK,iBAAiB,EAA8C,MAAM,OAAO,CAAC;AAMlG,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAQjF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IAEtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,WAAW,EAAE,KAAK,GAAG,IAAI,CAAC;IAC1B,QAAQ,CAAC,EAAE,YAAY,CAAC;IAExB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC,CAAC;AAQF,KAAK,eAAe,GAAG,iBAAiB,CAAC;IAEvC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX;;;;OAIG;IACH,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,GAAG,SAAS,CAAC;IAC1D,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACzC,CAAC,CAAC;AAEH;;;;;GAKG;AACH,QAAA,MAAM,UAAU;YAAW,eAAe;;CAgDzC,CAAC;AAUF,KAAK,kBAAkB,GAAG,eAAe,CAAC;AAsB1C,KAAK,iBAAiB,GAAG,eAAe,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAiCH,KAAK,gBAAgB,GAAG,eAAe,CAAC;AA+BxC,KAAK,mBAAmB,GAAG,eAAe,CAAC;AAmB3C,KAAK,eAAe,GAAG,eAAe,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAiCH,eAAO,MAAM,MAAM;IACjB,IAAI;IACJ,OAAO;;;IACP,MAAM;sBA1HQ,MAAM;;;;IA2HpB,KAAK;;;IACL,QAAQ;;;IACR,IAAI;;;CACL,CAAC;AAEF,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,GACpB,CAAC"}
|
|
@@ -3,7 +3,7 @@ import React from 'react';
|
|
|
3
3
|
declare const meta: {
|
|
4
4
|
title: string;
|
|
5
5
|
component: {
|
|
6
|
-
(props: import("./
|
|
6
|
+
(props: import("./Syntax.tsx").SyntaxRootProps): React.JSX.Element;
|
|
7
7
|
displayName: string;
|
|
8
8
|
};
|
|
9
9
|
decorators: import("@storybook/react").Decorator[];
|