@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.
Files changed (42) hide show
  1. package/dist/lib/index.mjs +197 -63
  2. package/dist/lib/index.mjs.map +1 -1
  3. package/dist/types/src/JsonHighlighter/JsonHighlighter.d.ts +4 -4
  4. package/dist/types/src/JsonHighlighter/JsonHighlighter.d.ts.map +1 -1
  5. package/dist/types/src/JsonHighlighter/JsonHighlighter.stories.d.ts +2 -2
  6. package/dist/types/src/JsonHighlighter/JsonHighlighter.stories.d.ts.map +1 -1
  7. package/dist/types/src/JsonHighlighter/index.d.ts +1 -1
  8. package/dist/types/src/JsonHighlighter/index.d.ts.map +1 -1
  9. package/dist/types/src/Syntax/Syntax.d.ts +5 -10
  10. package/dist/types/src/Syntax/Syntax.d.ts.map +1 -1
  11. package/dist/types/src/Syntax/Syntax.stories.d.ts +1 -1
  12. package/dist/types/src/Syntax/SyntaxContext.d.ts +3 -12
  13. package/dist/types/src/Syntax/SyntaxContext.d.ts.map +1 -1
  14. package/dist/types/src/Syntax/index.d.ts +1 -2
  15. package/dist/types/src/Syntax/index.d.ts.map +1 -1
  16. package/dist/types/src/SyntaxHighlighter/SyntaxHighlighter.d.ts +8 -4
  17. package/dist/types/src/SyntaxHighlighter/SyntaxHighlighter.d.ts.map +1 -1
  18. package/dist/types/src/SyntaxHighlighter/SyntaxHighlighter.stories.d.ts +2 -2
  19. package/dist/types/src/SyntaxHighlighter/SyntaxHighlighter.stories.d.ts.map +1 -1
  20. package/dist/types/src/SyntaxHighlighter/index.d.ts +1 -1
  21. package/dist/types/src/SyntaxHighlighter/index.d.ts.map +1 -1
  22. package/dist/types/src/SyntaxHighlighter/renderer.d.ts +10 -0
  23. package/dist/types/src/SyntaxHighlighter/renderer.d.ts.map +1 -0
  24. package/dist/types/src/SyntaxHighlighter/renderer.test.d.ts +2 -0
  25. package/dist/types/src/SyntaxHighlighter/renderer.test.d.ts.map +1 -0
  26. package/dist/types/src/index.d.ts +3 -3
  27. package/dist/types/src/index.d.ts.map +1 -1
  28. package/dist/types/tsconfig.tsbuildinfo +1 -1
  29. package/package.json +11 -11
  30. package/src/JsonHighlighter/JsonHighlighter.stories.tsx +1 -1
  31. package/src/JsonHighlighter/JsonHighlighter.tsx +7 -6
  32. package/src/JsonHighlighter/index.ts +1 -1
  33. package/src/Syntax/Syntax.stories.tsx +1 -1
  34. package/src/Syntax/Syntax.tsx +59 -60
  35. package/src/Syntax/SyntaxContext.ts +3 -6
  36. package/src/Syntax/index.ts +1 -3
  37. package/src/SyntaxHighlighter/SyntaxHighlighter.stories.tsx +1 -1
  38. package/src/SyntaxHighlighter/SyntaxHighlighter.tsx +137 -39
  39. package/src/SyntaxHighlighter/index.ts +1 -1
  40. package/src/SyntaxHighlighter/renderer.test.tsx +52 -0
  41. package/src/SyntaxHighlighter/renderer.ts +118 -0
  42. package/src/index.ts +3 -3
@@ -1,13 +1,96 @@
1
- import { Children, forwardRef, useCallback, useMemo, useState } from "react";
2
- import { Clipboard, Input, ScrollArea, composable, composableProps, useThemeContext } from "@dxos/react-ui";
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
- * Inline, non-scrolling wrapper around `react-syntax-highlighter`.
19
- *
20
- * Use directly for small snippets (e.g. inside markdown code blocks).
21
- * For scrollable panels, compose with `Syntax.Viewport`.
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(({ classNames, className, children, role, style, themeStyle, language = "text", fallback = zeroWidthSpace, copyButton, ...nativeProps }, forwardedRef) => {
30
- const { themeMode } = useThemeContext();
31
- const source = Children.toArray(children).join("") || fallback;
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-expander p-1 overflow-auto", copyButton && "relative group")
167
+ classNames: mx("dx-expand overflow-visible p-1", copyButton && "relative group")
42
168
  }),
43
169
  ref: forwardedRef,
44
- children: [/* @__PURE__ */ jsx(NativeSyntaxHighlighter, {
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("div", {
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
- * Inline, non-scrolling JSON renderer.
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
- * For filtering and scroll behaviour, compose with the `Syntax.*` namespace.
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
- //#endregion
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 { __scopeSyntax, children, language, source, replacer, getReplacer, defaultDepth = 0, onDepthChange } = props;
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 h-full min-h-0 overflow-hidden" }),
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(({ __scopeSyntax, classNames, placeholder = "JSONPath (e.g., $.graph.nodes)" }, forwardedRef) => {
176
- const { mode, filterText, setFilterText, filterError } = useSyntaxContext(SYNTAX_FILTER_NAME, __scopeSyntax);
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(Input.Root, {
313
+ return /* @__PURE__ */ jsx(Field.Root, {
179
314
  validationValence: filterError ? "error" : "success",
180
- children: /* @__PURE__ */ jsx(Input.TextInput, {
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(({ __scopeSyntax, classNames }, forwardedRef) => {
201
- const { depth, setDepth } = useSyntaxContext(SYNTAX_DEPTH_NAME, __scopeSyntax);
202
- return /* @__PURE__ */ jsx(Input.Root, { children: /* @__PURE__ */ jsx(Input.TextInput, {
203
- classNames: ["p-1 px-2 font-mono", 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
- onChange: (event) => setDepth(Math.max(0, Number(event.target.value) || 0)),
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` context. */
229
- var SyntaxCode = composable(({ __scopeSyntax, testId, ...props }, forwardedRef) => {
230
- const context = useSyntaxContext(SYNTAX_CODE_NAME, __scopeSyntax);
231
- const merged = composableProps(props, { classNames: "py-1 px-2 text-sm" });
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, createSyntaxScope };
391
+ export { JsonHighlighter, Syntax, SyntaxHighlighter, createElement };
258
392
 
259
393
  //# sourceMappingURL=index.mjs.map
@@ -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
- * Inline, non-scrolling JSON renderer.
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
- * For filtering and scroll behaviour, compose with the `Syntax.*` namespace.
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,sBAAsB,CAAC;AAEtF,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;AASF;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;6GAQ3B,CAAC"}
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,mBAAmB,CAAC;AAmCpD,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
+ {"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,mBAAmB,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: SyntaxScopedProps<SyntaxRootProps>): React.JSX.Element;
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<SyntaxScopedProps<SyntaxCodeProps>, "className"> & {
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;AAIlG,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEtD,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAExE,OAAO,EAAkB,KAAK,iBAAiB,EAAoB,MAAM,iBAAiB,CAAC;AAM3F,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,iBAAiB,CAAC,eAAe,CAAC;;CAiD5D,CAAC;AAUF,KAAK,kBAAkB,GAAG,eAAe,CAAC;AAmB1C,KAAK,iBAAiB,GAAG,eAAe,CAAC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAiCH,KAAK,gBAAgB,GAAG,eAAe,CAAC;AAmCxC,KAAK,mBAAmB,GAAG,eAAe,CAAC;AAmB3C,KAAK,eAAe,GAAG,eAAe,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAkCH,eAAO,MAAM,MAAM;IACjB,IAAI;IACJ,OAAO;;;IACP,MAAM;sBA/HQ,MAAM;;;;;;IAgIpB,KAAK;;;;;IACL,QAAQ;;;IACR,IAAI;;;CACL,CAAC;AAEF,YAAY,EACV,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,GACpB,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("./SyntaxContext").SyntaxScopedProps<import("./Syntax").SyntaxRootProps>): React.JSX.Element;
6
+ (props: import("./Syntax.tsx").SyntaxRootProps): React.JSX.Element;
7
7
  displayName: string;
8
8
  };
9
9
  decorators: import("@storybook/react").Decorator[];