@keboola/design 6.5.0 → 9.0.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 (49) hide show
  1. package/AGENTS.md +7 -7
  2. package/COMPONENT-API.md +3 -9
  3. package/README.md +1 -1
  4. package/dist/charts.cjs +22 -22
  5. package/dist/charts.cjs.map +1 -1
  6. package/dist/charts.d.cts +5 -5
  7. package/dist/charts.d.ts +5 -5
  8. package/dist/charts.js +22 -22
  9. package/dist/charts.js.map +1 -1
  10. package/dist/editors.cjs +904 -550
  11. package/dist/editors.cjs.map +1 -1
  12. package/dist/editors.d.cts +35 -5
  13. package/dist/editors.d.ts +35 -5
  14. package/dist/editors.js +908 -537
  15. package/dist/editors.js.map +1 -1
  16. package/dist/icons.cjs +23817 -45
  17. package/dist/icons.cjs.map +1 -1
  18. package/dist/icons.d.cts +12 -3
  19. package/dist/icons.d.ts +12 -3
  20. package/dist/icons.js +297 -40
  21. package/dist/icons.js.map +1 -1
  22. package/dist/index.cjs +4702 -4755
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.cts +183 -169
  25. package/dist/index.d.ts +183 -169
  26. package/dist/index.js +4700 -4754
  27. package/dist/index.js.map +1 -1
  28. package/dist/markdown-editor.cjs +817 -923
  29. package/dist/markdown-editor.cjs.map +1 -1
  30. package/dist/markdown-editor.js +818 -923
  31. package/dist/markdown-editor.js.map +1 -1
  32. package/dist/mermaid.cjs +308 -425
  33. package/dist/mermaid.cjs.map +1 -1
  34. package/dist/mermaid.d.cts +5 -1
  35. package/dist/mermaid.d.ts +5 -1
  36. package/dist/mermaid.js +310 -408
  37. package/dist/mermaid.js.map +1 -1
  38. package/dist/rjsf.cjs +1704 -1234
  39. package/dist/rjsf.cjs.map +1 -1
  40. package/dist/rjsf.js +1708 -1237
  41. package/dist/rjsf.js.map +1 -1
  42. package/dist/styles.css +2 -5
  43. package/dist/testing.cjs +86 -82
  44. package/dist/testing.cjs.map +1 -1
  45. package/dist/testing.js +86 -82
  46. package/dist/testing.js.map +1 -1
  47. package/package.json +26 -19
  48. package/src/styles.css +125 -105
  49. package/src/theme.css +264 -0
package/dist/editors.cjs CHANGED
@@ -14,61 +14,28 @@ var classVarianceAuthority = require('class-variance-authority');
14
14
  var brandRegistry = require('@keboola/brand-registry');
15
15
  var jsxRuntime = require('react/jsx-runtime');
16
16
  var reactSlot = require('@radix-ui/react-slot');
17
- var lucide_react_star = require('lucide-react');
17
+ var lucideReact = require('lucide-react');
18
18
  var langJavascript = require('@codemirror/lang-javascript');
19
19
  var langPython = require('@codemirror/lang-python');
20
20
  var langSql = require('@codemirror/lang-sql');
21
21
  var language = require('@codemirror/language');
22
22
  var r = require('@codemirror/legacy-modes/mode/r');
23
23
  var shell = require('@codemirror/legacy-modes/mode/shell');
24
+ var toml = require('@codemirror/legacy-modes/mode/toml');
24
25
  var codemirrorThemeGithub = require('@uiw/codemirror-theme-github');
25
26
  var codemirrorLangSfsql = require('@keboola/codemirror-lang-sfsql');
26
27
  var colors = require('@keboola/tailwind-config/colors');
28
+ var simpleMode = require('@codemirror/legacy-modes/mode/simple-mode');
29
+ var state = require('@codemirror/state');
27
30
  var commands = require('@codemirror/commands');
28
31
  var codemirrorLangSql = require('@keboola/codemirror-lang-sql');
29
- var state = require('@codemirror/state');
30
32
 
31
33
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
32
34
 
33
- function _interopNamespace(e) {
34
- if (e && e.__esModule) return e;
35
- var n = Object.create(null);
36
- if (e) {
37
- Object.keys(e).forEach(function (k) {
38
- if (k !== 'default') {
39
- var d = Object.getOwnPropertyDescriptor(e, k);
40
- Object.defineProperty(n, k, d.get ? d : {
41
- enumerable: true,
42
- get: function () { return e[k]; }
43
- });
44
- }
45
- });
46
- }
47
- n.default = e;
48
- return Object.freeze(n);
49
- }
50
-
51
35
  var CodeMirror__default = /*#__PURE__*/_interopDefault(CodeMirror);
52
- var lucide_react_star__namespace = /*#__PURE__*/_interopNamespace(lucide_react_star);
53
36
  var colors__default = /*#__PURE__*/_interopDefault(colors);
54
37
 
55
- var __defProp = Object.defineProperty;
56
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
57
- var __getOwnPropNames = Object.getOwnPropertyNames;
58
- var __hasOwnProp = Object.prototype.hasOwnProperty;
59
- var __export = (target, all) => {
60
- for (var name in all)
61
- __defProp(target, name, { get: all[name], enumerable: true });
62
- };
63
- var __copyProps = (to, from, except, desc) => {
64
- if (from && typeof from === "object" || typeof from === "function") {
65
- for (let key of __getOwnPropNames(from))
66
- if (!__hasOwnProp.call(to, key) && key !== except)
67
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
68
- }
69
- return to;
70
- };
71
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget);
38
+ // src/components/CodeEditor/CodeEditor.tsx
72
39
 
73
40
  // src/constants/keyCodes.ts
74
41
  var keyCodes = {
@@ -76,8 +43,15 @@ var keyCodes = {
76
43
  ESCAPE: "Escape",
77
44
  SPACE: " "
78
45
  };
46
+ var useStableCallback = (callback) => {
47
+ const latestRef = react.useRef(callback);
48
+ react.useLayoutEffect(() => {
49
+ latestRef.current = callback;
50
+ }, [callback]);
51
+ return react.useCallback((...args) => latestRef.current(...args), []);
52
+ };
79
53
  var twMerge = tailwindMerge.extendTailwindMerge({
80
- prefix: "tw-"
54
+ prefix: "tw"
81
55
  });
82
56
  var cn = (...classes) => twMerge(clsx.clsx(...classes));
83
57
 
@@ -121,39 +95,39 @@ var useArgoDesign = () => react.use(ArgoDesignContext);
121
95
  var tooltipVariants = classVarianceAuthority.cva(
122
96
  [
123
97
  "tailwindcss-preflight",
124
- "tw-inline-block",
125
- "tw-break-anywhere",
126
- "tw-max-h-96",
127
- "tw-overflow-y-auto",
128
- "tw-z-[1060]",
98
+ "tw:inline-block",
99
+ "tw:break-anywhere",
100
+ "tw:max-h-96",
101
+ "tw:overflow-y-auto",
102
+ "tw:z-[1060]",
129
103
  // legacy (dark) chrome — default
130
- "tw-rounded",
131
- "tw-bg-neutral-800",
132
- "tw-text-white",
104
+ "tw:rounded",
105
+ "tw:bg-neutral-800",
106
+ "tw:text-white",
133
107
  // argo chrome overrides — semantic floating-panel tokens
134
- "data-[argo=true]:tw-rounded-2xl",
135
- "data-[argo=true]:tw-border",
136
- "data-[argo=true]:tw-border-solid",
137
- "data-[argo=true]:tw-border-border",
138
- "data-[argo=true]:tw-bg-popover",
139
- "data-[argo=true]:tw-text-popover-foreground",
140
- "data-[argo=true]:tw-shadow-md",
108
+ "tw:data-[argo=true]:rounded-2xl",
109
+ "tw:data-[argo=true]:border",
110
+ "tw:data-[argo=true]:border-solid",
111
+ "tw:data-[argo=true]:border-border",
112
+ "tw:data-[argo=true]:bg-popover",
113
+ "tw:data-[argo=true]:text-popover-foreground",
114
+ "tw:data-[argo=true]:shadow-md",
141
115
  // argo open animation
142
- "data-[argo=true]:data-[state=delayed-open]:tw-animate-in",
143
- "data-[argo=true]:data-[state=instant-open]:tw-animate-in",
144
- "data-[argo=true]:data-[state=delayed-open]:tw-fade-in-0",
145
- "data-[argo=true]:data-[state=instant-open]:tw-fade-in-0",
146
- "data-[argo=true]:data-[state=delayed-open]:tw-zoom-in-95",
147
- "data-[argo=true]:data-[state=instant-open]:tw-zoom-in-95",
116
+ "tw:data-[argo=true]:data-[state=delayed-open]:animate-in",
117
+ "tw:data-[argo=true]:data-[state=instant-open]:animate-in",
118
+ "tw:data-[argo=true]:data-[state=delayed-open]:fade-in-0",
119
+ "tw:data-[argo=true]:data-[state=instant-open]:fade-in-0",
120
+ "tw:data-[argo=true]:data-[state=delayed-open]:zoom-in-95",
121
+ "tw:data-[argo=true]:data-[state=instant-open]:zoom-in-95",
148
122
  // argo closed animation
149
- "data-[argo=true]:data-[state=closed]:tw-animate-out",
150
- "data-[argo=true]:data-[state=closed]:tw-fade-out-0",
151
- "data-[argo=true]:data-[state=closed]:tw-zoom-out-95",
123
+ "tw:data-[argo=true]:data-[state=closed]:animate-out",
124
+ "tw:data-[argo=true]:data-[state=closed]:fade-out-0",
125
+ "tw:data-[argo=true]:data-[state=closed]:zoom-out-95",
152
126
  // argo position animation
153
- "data-[argo=true]:data-[side=bottom]:tw-slide-in-from-top-2",
154
- "data-[argo=true]:data-[side=left]:tw-slide-in-from-right-2",
155
- "data-[argo=true]:data-[side=right]:tw-slide-in-from-left-2",
156
- "data-[argo=true]:data-[side=top]:tw-slide-in-from-bottom-2"
127
+ "tw:data-[argo=true]:data-[side=bottom]:slide-in-from-top-2",
128
+ "tw:data-[argo=true]:data-[side=left]:slide-in-from-right-2",
129
+ "tw:data-[argo=true]:data-[side=right]:slide-in-from-left-2",
130
+ "tw:data-[argo=true]:data-[side=top]:slide-in-from-bottom-2"
157
131
  ],
158
132
  {
159
133
  defaultVariants: {
@@ -162,22 +136,26 @@ var tooltipVariants = classVarianceAuthority.cva(
162
136
  variants: {
163
137
  variant: {
164
138
  action: [
165
- "tw-max-w-fit",
166
- "tw-px-3",
167
- "tw-py-2",
168
- "tw-text-center",
169
- "tw-text-xs",
170
- "tw-font-medium",
171
- "tw-uppercase",
172
- "tw-tracking-wider"
139
+ "tw:max-w-fit",
140
+ "tw:px-3",
141
+ "tw:py-2",
142
+ "tw:text-center",
143
+ "tw:text-xs",
144
+ "tw:font-medium",
145
+ // Legacy chrome uppercases the action tooltip; the Keboola V2 brand
146
+ // (`data-brand="keboola"`) renders it in standard case instead.
147
+ "tw:uppercase",
148
+ "tw:tracking-wider",
149
+ "tw:[[data-brand=keboola]_&]:normal-case",
150
+ "tw:[[data-brand=keboola]_&]:tracking-normal"
173
151
  ],
174
152
  explanatory: [
175
- "tw-max-w-80",
176
- "tw-px-4",
177
- "tw-py-3",
178
- "tw-text-left",
179
- "tw-text-sm",
180
- "tw-font-normal"
153
+ "tw:max-w-80",
154
+ "tw:px-4",
155
+ "tw:py-3",
156
+ "tw:text-left",
157
+ "tw:text-sm",
158
+ "tw:font-normal"
181
159
  ]
182
160
  }
183
161
  }
@@ -251,8 +229,8 @@ var TooltipTrigger = ({
251
229
  // (merged in via Slot) activates Tailwind's preflight inside the
252
230
  // span, which sets `svg { display: block }` — without an inline-flex
253
231
  // container that would stack any bare Lucide icon onto its own
254
- // line. `tw-inline-flex tw-items-center` keeps icon + text aligned.
255
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tw-inline-flex tw-items-center", children })
232
+ // line. `tw:inline-flex tw:items-center` keeps icon + text aligned.
233
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tw:inline-flex tw:items-center", children })
256
234
  )
257
235
  }
258
236
  );
@@ -319,14 +297,29 @@ Tooltip.Trigger = TooltipTrigger;
319
297
 
320
298
  // src/utils/escapeStringRegexp.ts
321
299
  var escapeStringRegexp = (string) => string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
322
- var helpVariants = classVarianceAuthority.cva(["tw-m-0", "tw-text-xs"], {
300
+
301
+ // src/utils/isMac.ts
302
+ var getIsMac = () => {
303
+ if (typeof navigator !== "undefined" && "userAgentData" in navigator) {
304
+ const platform = navigator.userAgentData.platform;
305
+ if (typeof platform === "string") {
306
+ return platform.toLowerCase() === "macos";
307
+ }
308
+ }
309
+ if (typeof navigator !== "undefined" && typeof navigator.platform === "string") {
310
+ return navigator.platform.toUpperCase().indexOf("MAC") >= 0;
311
+ }
312
+ return false;
313
+ };
314
+ var isMac = getIsMac();
315
+ var helpVariants = classVarianceAuthority.cva(["tw:m-0", "tw:text-xs"], {
323
316
  defaultVariants: {
324
317
  state: "default"
325
318
  },
326
319
  variants: {
327
320
  state: {
328
- default: ["tw-text-muted-foreground"],
329
- warning: ["tw-text-warning"]
321
+ default: ["tw:text-muted-foreground"],
322
+ warning: ["tw:text-warning"]
330
323
  }
331
324
  }
332
325
  });
@@ -334,146 +327,49 @@ var HelpBlock = ({ children, className, state = "default", ...rest }) => {
334
327
  if (!children) return null;
335
328
  return /* @__PURE__ */ jsxRuntime.jsx("p", { ...rest, className: helpVariants({ state, className }), children });
336
329
  };
337
-
338
- // src/icons/index.ts
339
- var icons_exports = {};
340
- __export(icons_exports, {
341
- Google: () => Google,
342
- Keboola: () => Keboola,
343
- Microsoft: () => Microsoft
344
- });
345
- __reExport(icons_exports, lucide_react_star__namespace);
346
- var Google = react.forwardRef(
347
- ({ size = 24, className, children, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
348
- "svg",
349
- {
350
- ref,
351
- xmlns: "http://www.w3.org/2000/svg",
352
- width: size,
353
- height: size,
354
- viewBox: "12 10 20 20",
355
- fill: "none",
356
- className: cn("lucide", className),
357
- ...rest,
358
- children: [
359
- /* @__PURE__ */ jsxRuntime.jsx(
360
- "path",
361
- {
362
- d: "M31.6 20.2273C31.6 19.5182 31.5364 18.8364 31.4182 18.1818H22V22.05H27.3818C27.15 23.3 26.4455 24.3591 25.3864 25.0682V27.5773H28.6182C30.5091 25.8364 31.6 23.2727 31.6 20.2273Z",
363
- fill: "#4285F4"
364
- }
365
- ),
366
- /* @__PURE__ */ jsxRuntime.jsx(
367
- "path",
368
- {
369
- d: "M22 30C24.7 30 26.9636 29.1045 28.6181 27.5773L25.3863 25.0682C24.4909 25.6682 23.3454 26.0227 22 26.0227C19.3954 26.0227 17.1909 24.2636 16.4045 21.9H13.0636V24.4909C14.7091 27.7591 18.0909 30 22 30Z",
370
- fill: "#34A853"
371
- }
372
- ),
373
- /* @__PURE__ */ jsxRuntime.jsx(
374
- "path",
375
- {
376
- d: "M16.4045 21.9C16.2045 21.3 16.0909 20.6591 16.0909 20C16.0909 19.3409 16.2045 18.7 16.4045 18.1V15.5091H13.0636C12.3864 16.8591 12 18.3864 12 20C12 21.6136 12.3864 23.1409 13.0636 24.4909L16.4045 21.9Z",
377
- fill: "#FBBC04"
378
- }
379
- ),
380
- /* @__PURE__ */ jsxRuntime.jsx(
381
- "path",
382
- {
383
- d: "M22 13.9773C23.4681 13.9773 24.7863 14.4818 25.8227 15.4727L28.6909 12.6045C26.9591 10.9909 24.6954 10 22 10C18.0909 10 14.7091 12.2409 13.0636 15.5091L16.4045 18.1C17.1909 15.7364 19.3954 13.9773 22 13.9773Z",
384
- fill: "#EA4335"
385
- }
386
- ),
387
- children
388
- ]
389
- }
390
- )
391
- );
392
- Google.displayName = "Google";
393
- var Keboola = react.forwardRef(
394
- ({ size = 24, color = "currentColor", className, children, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
395
- "svg",
396
- {
397
- ref,
398
- xmlns: "http://www.w3.org/2000/svg",
399
- width: size,
400
- height: size,
401
- viewBox: "0 0 300 512",
402
- overflow: "visible",
403
- fill: color,
404
- className: cn("lucide", className),
405
- ...rest,
406
- children: [
407
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M152 320C79.7 320 24.5 233.9 24.5 124.7C24.5 15.6 70.5 0 152 0s123.6 15.6 123.6 124.7C275.5 233.9 217.7 320 152 320zm-8.7-50.5c0-11.2-9.5-20.3-21.2-20.3s-21.2 9.1-21.2 20.3c0 11.2 9.5 20.3 21.2 20.3s21.2-9.1 21.2-20.3zm55.7 0c0-11.2-9.5-20.3-21.2-20.3s-21.2 9.1-21.2 20.3c0 11.2 9.5 20.3 21.2 20.3s21.2-9.1 21.2-20.3zm68.9 115.1c10.2 9.3 20.2 20.5 29 35c5.9 9.7 2.6 22.1-7.5 27.8c-3.4 1.9-7.1 2.8-10.7 2.8c-7.2 0-14.3-3.6-18.3-10c-6.8-11.1-13.8-18.9-21.7-26.1c-7.3-6.7-15.6-12.7-24.9-19.5c-.7-.5-1.4-1-2.1-1.5c-5-3.6-10-6.8-14.9-9.4c.6 1 1.2 2.1 1.8 3.2c14.4 26.4 29.2 63.1 29.2 104.9c0 11.2-9.5 20.3-21.2 20.3c-11.7 0-21.2-9.1-21.2-20.3c.1-31.8-11.6-62.3-23.8-84.9c-4-7.4-8-13.9-11.6-19.3c-3.4 5.2-7.2 11.3-11 18.3c-12.5 22.7-24.5 53.8-24.4 86c0 11.2-9.5 20.3-21.2 20.3s-21.2-9.1-21.2-20.3c.1-41.8 14.9-78.4 29.2-104.9c.6-1.1 1.2-2.1 1.8-3.2c-5 2.7-9.9 5.8-14.9 9.4c-.6 .5-1.3 .9-1.9 1.4c-9.5 6.9-17.8 12.9-25.1 19.7c-7.9 7.2-14.9 15.1-21.7 26.1c-5.9 9.7-18.9 12.9-29 7.2C.5 441.8-2.9 429.3 3.1 419.7c8.9-14.4 18.8-25.7 29-35c9.2-8.4 18.5-15.1 27.6-21.7c1-.7 2-1.4 3-2.2c4.7-3.5 9.6-6.7 14.6-9.6c-5-2.9-9.8-6.1-14.6-9.6C39.8 325 19.9 302.5 3.1 275.1c-5.9-9.7-2.6-22.1 7.5-27.8c10.1-5.7 23.1-2.5 29 7.2c14.6 23.7 31.1 42 48.7 54.9c18.9 13.7 37.4 20.5 56.5 21.5c1.7-.1 3.5-.1 5.2-.1c1.8 0 3.5 .1 5.2 .1c0 0 0 0 0 0c19.1-1.1 37.6-7.9 56.5-21.5c17.6-12.8 34.2-31.2 48.7-54.9c6-9.7 18.9-12.9 29-7.2c10.1 5.7 13.4 18.1 7.5 27.8c-16.8 27.4-36.7 49.9-59.6 66.6c-4.7 3.5-9.6 6.7-14.5 9.6c4.9 2.9 9.8 6.1 14.5 9.6c.9 .7 1.8 1.3 2.7 2c9.2 6.7 18.5 13.5 27.9 22z" }),
408
- children
409
- ]
410
- }
411
- )
412
- );
413
- Keboola.displayName = "Keboola";
414
- var Microsoft = react.forwardRef(
415
- ({ size = 24, className, children, ...rest }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
416
- "svg",
417
- {
418
- ref,
419
- xmlns: "http://www.w3.org/2000/svg",
420
- width: size,
421
- height: size,
422
- viewBox: "0 0 21 21",
423
- fill: "none",
424
- className: cn("lucide", className),
425
- ...rest,
426
- children: [
427
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0", y: "0", width: "10", height: "10", fill: "#F25022" }),
428
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "11", y: "0", width: "10", height: "10", fill: "#7FBA00" }),
429
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "0", y: "11", width: "10", height: "10", fill: "#00A4EF" }),
430
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "11", y: "11", width: "10", height: "10", fill: "#FFB900" }),
431
- children
432
- ]
433
- }
434
- )
435
- );
436
- Microsoft.displayName = "Microsoft";
437
330
  var variants = classVarianceAuthority.cva(
438
331
  [
439
332
  "tailwindcss-preflight",
440
- "tw-group/button",
441
- "tw-border-box",
333
+ "tw:group/button",
334
+ "tw:border-box",
442
335
  // layout
443
- "tw-relative",
444
- "tw-flex",
445
- "tw-items-center",
446
- "tw-justify-center",
447
- "tw-gap-2",
336
+ "tw:relative",
337
+ "tw:flex",
338
+ "tw:items-center",
339
+ "tw:justify-center",
340
+ "tw:gap-2",
448
341
  // text — chrome weight/tracking are brand-overridable tokens
449
- // (`--font-weight-medium` / `--letter-spacing-chrome`); casing stays `tw-uppercase`.
450
- "tw-text-xs",
451
- "tw-leading-5",
452
- "tw-font-medium",
453
- "tw-tracking-chrome",
454
- "tw-uppercase",
342
+ // (`--font-weight-medium` / `--letter-spacing-chrome`). Casing: standard case is
343
+ // the default; only legacy brands (`keboola-legacy-*`) uppercase the chrome, so
344
+ // modern brands (incl. Keboola V2) read naturally. Mirrors the V2 standard-case
345
+ // treatment shipped for Tooltip/Badge (PR 7629).
346
+ "tw:text-xs",
347
+ "tw:leading-5",
348
+ "tw:font-medium",
349
+ "tw:[[data-brand^=keboola-legacy]_&]:tracking-chrome",
350
+ "tw:[[data-brand^=keboola-legacy]_&]:uppercase",
455
351
  // border — legacy (non-argo) chrome uses a fixed radius, not the brand token.
456
- "tw-rounded",
457
- "tw-border",
458
- "tw-border-transparent",
352
+ "tw:rounded",
353
+ "tw:border",
354
+ "tw:border-transparent",
459
355
  // styling
460
- "tw-shadow-none",
461
- "[a]:tw-cursor-pointer",
356
+ "tw:shadow-none",
357
+ "tw:[a]:cursor-pointer",
462
358
  // explicitly set for anchor
463
- "focus-visible:tw-outline",
464
- "focus-visible:tw-outline-1",
465
- "focus-visible:-tw-outline-offset-1",
466
- "focus-visible:tw-outline-ring",
467
- "focus-visible:tw-ring-4",
468
- "focus-visible:tw-ring-ring/30",
359
+ "tw:focus-visible:outline",
360
+ "tw:focus-visible:outline-1",
361
+ "tw:focus-visible:-outline-offset-1",
362
+ "tw:focus-visible:outline-ring",
363
+ "tw:focus-visible:ring-4",
364
+ "tw:focus-visible:ring-ring/30",
469
365
  // disabled
470
- "disabled:tw-opacity-40",
471
- "disabled:tw-cursor-not-allowed",
366
+ "tw:disabled:opacity-40",
367
+ "tw:disabled:cursor-not-allowed",
472
368
  // anchor support
473
- "!tw-no-underline",
474
- "aria-disabled:tw-opacity-40",
475
- "aria-disabled:tw-cursor-not-allowed",
476
- "[&_svg]:tw-shrink-0"
369
+ "tw:!no-underline",
370
+ "tw:aria-disabled:opacity-40",
371
+ "tw:aria-disabled:cursor-not-allowed",
372
+ "tw:[&_svg]:shrink-0"
477
373
  ],
478
374
  {
479
375
  defaultVariants: {
@@ -483,113 +379,113 @@ var variants = classVarianceAuthority.cva(
483
379
  },
484
380
  variants: {
485
381
  block: {
486
- true: ["tw-w-full"]
382
+ true: ["tw:w-full"]
487
383
  },
488
384
  variant: {
489
385
  primary: [
490
- "tw-text-white",
491
- "tw-bg-primary-500",
492
- "focus:tw-text-white",
493
- "hover:tw-text-white",
494
- "hover:not-disabled:tw-bg-primary-600",
495
- "active:not-disabled:tw-bg-primary-800",
386
+ "tw:text-white",
387
+ "tw:bg-primary-500",
388
+ "tw:focus:text-white",
389
+ "tw:hover:text-white",
390
+ "tw:hover:not-disabled:bg-primary-600",
391
+ "tw:active:not-disabled:bg-primary-800",
496
392
  // anchor disabled override
497
- "aria-disabled:!tw-bg-primary-500"
393
+ "tw:aria-disabled:!bg-primary-500"
498
394
  ],
499
395
  secondary: [
500
- "tw-text-white",
501
- "tw-bg-secondary-500",
502
- "focus:tw-text-white",
503
- "hover:tw-text-white",
504
- "hover:not-disabled:tw-bg-secondary-700",
505
- "active:not-disabled:tw-bg-secondary-800",
396
+ "tw:text-white",
397
+ "tw:bg-secondary-500",
398
+ "tw:focus:text-white",
399
+ "tw:hover:text-white",
400
+ "tw:hover:not-disabled:bg-secondary-700",
401
+ "tw:active:not-disabled:bg-secondary-800",
506
402
  // anchor disabled override
507
- "aria-disabled:!tw-bg-secondary-500"
403
+ "tw:aria-disabled:!bg-secondary-500"
508
404
  ],
509
405
  danger: [
510
- "tw-text-white",
511
- "tw-bg-error-500",
512
- "focus:tw-text-white",
513
- "hover:tw-text-white",
514
- "hover:not-disabled:tw-bg-error-600",
515
- "active:not-disabled:tw-bg-error-700",
406
+ "tw:text-white",
407
+ "tw:bg-error-500",
408
+ "tw:focus:text-white",
409
+ "tw:hover:text-white",
410
+ "tw:hover:not-disabled:bg-error-600",
411
+ "tw:active:not-disabled:bg-error-700",
516
412
  // anchor disabled override
517
- "aria-disabled:!tw-bg-error-500"
413
+ "tw:aria-disabled:!bg-error-500"
518
414
  ],
519
415
  invisible: [
520
- "tw-text-neutral-800",
521
- "tw-bg-transparent",
522
- "focus:tw-text-neutral-800",
523
- "hover:not-disabled:tw-bg-neutral-100",
524
- "hover:tw-text-neutral-800",
525
- "active:not-disabled:tw-bg-neutral-150",
416
+ "tw:text-neutral-800",
417
+ "tw:bg-transparent",
418
+ "tw:focus:text-neutral-800",
419
+ "tw:hover:not-disabled:bg-neutral-100",
420
+ "tw:hover:text-neutral-800",
421
+ "tw:active:not-disabled:bg-neutral-150",
526
422
  // contrasting icon on hover/active
527
- "[&_svg]:tw-text-neutral-400",
528
- "[&_svg]:hover:not-disabled:tw-text-secondary-600",
529
- "[&_svg]:active:not-disabled:tw-text-secondary-600",
423
+ "tw:[&_svg]:text-neutral-400",
424
+ "tw:hover:not-disabled:[&_svg]:text-secondary-600",
425
+ "tw:active:not-disabled:[&_svg]:text-secondary-600",
530
426
  // anchor disabled override
531
- "aria-disabled:!tw-bg-transparent"
427
+ "tw:aria-disabled:!bg-transparent"
532
428
  ],
533
429
  outline: [
534
- "tw-text-neutral-800",
535
- "tw-bg-white",
430
+ "tw:text-neutral-800",
431
+ "tw:bg-white",
536
432
  // border
537
- "!tw-border-neutral-200",
538
- "hover:tw-text-neutral-800",
539
- "focus:tw-text-neutral-800",
540
- "hover:not-disabled:!tw-border-neutral-300",
541
- "hover:not-disabled:tw-bg-neutral-100",
542
- "active:not-disabled:tw-bg-neutral-200",
433
+ "tw:!border-neutral-200",
434
+ "tw:hover:text-neutral-800",
435
+ "tw:focus:text-neutral-800",
436
+ "tw:hover:not-disabled:!border-neutral-300",
437
+ "tw:hover:not-disabled:bg-neutral-100",
438
+ "tw:active:not-disabled:bg-neutral-200",
543
439
  // contrasting icon hover, same as invisible
544
- "[&_svg]:tw-text-neutral-400",
545
- "[&_svg]:not-disabled:hover:tw-text-secondary-600",
546
- "[&_svg]:active:not-disabled:tw-text-secondary-600",
440
+ "tw:[&_svg]:text-neutral-400",
441
+ "tw:not-disabled:hover:[&_svg]:text-secondary-600",
442
+ "tw:active:not-disabled:[&_svg]:text-secondary-600",
547
443
  // anchor disabled override
548
- "aria-disabled:!tw-bg-white",
549
- "aria-disabled:!tw-border-neutral-200"
444
+ "tw:aria-disabled:!bg-white",
445
+ "tw:aria-disabled:!border-neutral-200"
550
446
  ],
551
447
  inline: [
552
- "tw-text-neutral-800",
553
- "tw-bg-transparent",
554
- "tw-rounded-full",
555
- "[&_svg]:tw-text-neutral-400",
556
- "[&_svg]:not-disabled:hover:tw-text-secondary-600",
557
- "[&_svg]:not-disabled:focus:tw-text-secondary-600"
448
+ "tw:text-neutral-800",
449
+ "tw:bg-transparent",
450
+ "tw:rounded-full",
451
+ "tw:[&_svg]:text-neutral-400",
452
+ "tw:not-disabled:hover:[&_svg]:text-secondary-600",
453
+ "tw:not-disabled:focus:[&_svg]:text-secondary-600"
558
454
  ]
559
455
  },
560
456
  size: {
561
457
  medium: [
562
- "tw-max-h-10",
563
- "tw-min-h-10",
564
- "tw-px-4",
565
- "tw-py-2.5",
566
- '[&_svg:not([class*="tw-size-"])]:tw-size-4'
458
+ "tw:max-h-10",
459
+ "tw:min-h-10",
460
+ "tw:px-4",
461
+ "tw:py-2.5",
462
+ 'tw:[&_svg:not([class*="tw:size-"])]:size-4'
567
463
  ],
568
464
  small: [
569
- "tw-max-h-8",
570
- "tw-min-h-8",
571
- "tw-px-4",
572
- "tw-py-1.5",
573
- '[&_svg:not([class*="tw-size-"])]:tw-size-4'
465
+ "tw:max-h-8",
466
+ "tw:min-h-8",
467
+ "tw:px-4",
468
+ "tw:py-1.5",
469
+ 'tw:[&_svg:not([class*="tw:size-"])]:size-4'
574
470
  ],
575
471
  large: [
576
- "tw-max-h-12",
577
- "tw-min-h-12",
578
- "tw-px-4",
579
- "tw-py-3.5",
580
- '[&_svg:not([class*="tw-size-"])]:tw-size-4'
472
+ "tw:max-h-12",
473
+ "tw:min-h-12",
474
+ "tw:px-4",
475
+ "tw:py-3.5",
476
+ 'tw:[&_svg:not([class*="tw:size-"])]:size-4'
581
477
  ],
582
- "icon-lg": ["tw-size-12", "tw-p-0", '[&_svg:not([class*="tw-size-"])]:tw-size-6'],
583
- icon: ["tw-size-10", "tw-p-0", '[&_svg:not([class*="tw-size-"])]:tw-size-4'],
584
- "icon-sm": ["tw-size-8", "tw-p-0", '[&_svg:not([class*="tw-size-"])]:tw-size-4'],
585
- "icon-xs": ["tw-size-6", "tw-p-0", '[&_svg:not([class*="tw-size-"])]:tw-size-4'],
478
+ "icon-lg": ["tw:size-12", "tw:p-0", 'tw:[&_svg:not([class*="tw:size-"])]:size-6'],
479
+ icon: ["tw:size-10", "tw:p-0", 'tw:[&_svg:not([class*="tw:size-"])]:size-4'],
480
+ "icon-sm": ["tw:size-8", "tw:p-0", 'tw:[&_svg:not([class*="tw:size-"])]:size-4'],
481
+ "icon-xs": ["tw:size-6", "tw:p-0", 'tw:[&_svg:not([class*="tw:size-"])]:size-4'],
586
482
  "icon-2xs": [
587
- "!tw-inline-flex",
588
- "tw-size-5",
589
- "tw-max-h-5",
590
- '[&_svg:not([class*="tw-size-"])]:tw-size-3'
483
+ "tw:!inline-flex",
484
+ "tw:size-5",
485
+ "tw:max-h-5",
486
+ 'tw:[&_svg:not([class*="tw:size-"])]:size-3'
591
487
  ],
592
- "icon-3xs": ["tw-h-fit", "tw-w-fit", '[&_svg:not([class*="tw-size-"])]:tw-size-4']
488
+ "icon-3xs": ["tw:h-fit", "tw:w-fit", 'tw:[&_svg:not([class*="tw:size-"])]:size-4']
593
489
  }
594
490
  }
595
491
  }
@@ -598,37 +494,37 @@ var argoVariants = classVarianceAuthority.cva(
598
494
  [
599
495
  "tailwindcss-preflight",
600
496
  // layout
601
- "tw-relative",
602
- "tw-inline-flex",
603
- "tw-items-center",
604
- "tw-justify-center",
605
- "tw-whitespace-nowrap",
606
- "tw-gap-2",
497
+ "tw:relative",
498
+ "tw:inline-flex",
499
+ "tw:items-center",
500
+ "tw:justify-center",
501
+ "tw:whitespace-nowrap",
502
+ "tw:gap-2",
607
503
  // border
608
- "tw-border",
609
- "tw-border-transparent",
610
- "tw-rounded-[var(--radius-lg,0.25rem)]",
504
+ "tw:border",
505
+ "tw:border-transparent",
506
+ "tw:rounded-[var(--radius-lg,0.25rem)]",
611
507
  // text
612
- "tw-font-medium",
613
- "tw-select-none",
508
+ "tw:font-medium",
509
+ "tw:select-none",
614
510
  // focus visible
615
- "!tw-outline-none",
616
- "focus-visible:tw-ring-2",
511
+ "tw:!outline-hidden",
512
+ "tw:focus-visible:ring-2",
617
513
  // disabled
618
- "disabled:tw-cursor-not-allowed",
619
- "disabled:tw-opacity-50",
620
- "active:tw-opacity-60",
621
- "tw-transition-all",
622
- "tw-bg-clip-padding",
514
+ "tw:disabled:cursor-not-allowed",
515
+ "tw:disabled:opacity-50",
516
+ "tw:active:opacity-60",
517
+ "tw:transition-all",
518
+ "tw:bg-clip-padding",
623
519
  // anchor support
624
- "!tw-no-underline",
625
- "aria-disabled:tw-cursor-not-allowed",
626
- "aria-disabled:tw-opacity-50",
520
+ "tw:!no-underline",
521
+ "tw:aria-disabled:cursor-not-allowed",
522
+ "tw:aria-disabled:opacity-50",
627
523
  // icon
628
- "tw-shrink-0",
629
- "[&_svg]:tw-pointer-events-none",
630
- "[&_svg]:tw-shrink-0",
631
- "[&_svg:not([class*='tw-size-'])]:tw-size-4"
524
+ "tw:shrink-0",
525
+ "tw:[&_svg]:pointer-events-none",
526
+ "tw:[&_svg]:shrink-0",
527
+ "tw:[&_svg:not([class*='tw:size-'])]:size-4"
632
528
  ],
633
529
  {
634
530
  defaultVariants: {
@@ -637,77 +533,77 @@ var argoVariants = classVarianceAuthority.cva(
637
533
  },
638
534
  variants: {
639
535
  block: {
640
- true: ["tw-w-full"]
536
+ true: ["tw:w-full"]
641
537
  },
642
538
  variant: {
643
539
  primary: [
644
- "tw-bg-primary",
645
- "tw-text-primary-foreground",
646
- "[a]:hover:tw-bg-primary/80",
647
- "hover:not-disabled:tw-bg-primary/90",
648
- "hover:tw-text-primary-foreground",
649
- "focus:tw-text-primary-foreground",
650
- "focus-visible:tw-border-primary",
651
- "focus-visible:tw-ring-ring/50"
540
+ "tw:bg-primary",
541
+ "tw:text-primary-foreground",
542
+ "tw:[a]:hover:bg-primary/80",
543
+ "tw:hover:not-disabled:bg-primary/90",
544
+ "tw:hover:text-primary-foreground",
545
+ "tw:focus:text-primary-foreground",
546
+ "tw:focus-visible:border-primary",
547
+ "tw:focus-visible:ring-ring/50"
652
548
  ],
653
549
  secondary: [
654
- "tw-bg-primary/10",
655
- "tw-text-primary",
656
- "hover:not-disabled:tw-bg-primary/20",
657
- "focus-visible:tw-border-primary",
658
- "focus-visible:tw-ring-ring/50"
550
+ "tw:bg-primary/10",
551
+ "tw:text-primary",
552
+ "tw:hover:not-disabled:bg-primary/20",
553
+ "tw:focus-visible:border-primary",
554
+ "tw:focus-visible:ring-ring/50"
659
555
  ],
660
556
  // should be called "destructive" by Figma
661
557
  danger: [
662
- "tw-bg-destructive",
663
- "tw-text-destructive-foreground",
664
- "hover:tw-text-destructive-foreground",
665
- "focus:tw-text-destructive-foreground",
666
- "focus-visible:tw-border-destructive",
667
- "focus-visible:tw-ring-destructive/20"
558
+ "tw:bg-destructive",
559
+ "tw:text-destructive-foreground",
560
+ "tw:hover:text-destructive-foreground",
561
+ "tw:focus:text-destructive-foreground",
562
+ "tw:focus-visible:border-destructive",
563
+ "tw:focus-visible:ring-destructive/20"
668
564
  ],
669
565
  outline: [
670
- "!tw-border-input",
671
- "tw-bg-background",
566
+ "tw:!border-input",
567
+ "tw:bg-background",
672
568
  // Semantic base text color so the label/icon flips in dark mode
673
569
  // (matches `invisible`); previously unset → inherited a fixed dark color.
674
- "tw-text-foreground",
570
+ "tw:text-foreground",
675
571
  // Hover follows the brand primary (translucent tint), matching the
676
572
  // `secondary` variant — not the fixed `accent` blue.
677
- "hover:not-disabled:tw-bg-primary/10",
678
- "hover:not-disabled:tw-text-primary",
679
- "hover:active:tw-bg-background",
680
- "focus-visible:!tw-border-primary",
681
- "focus-visible:tw-ring-ring/50"
573
+ "tw:hover:not-disabled:bg-primary/10",
574
+ "tw:hover:not-disabled:text-primary",
575
+ "tw:hover:active:bg-background",
576
+ "tw:focus-visible:!border-primary",
577
+ "tw:focus-visible:ring-ring/50"
682
578
  ],
683
579
  // should be called "ghost" by Figma
684
580
  invisible: [
685
- "tw-bg-transparent",
686
- "tw-text-foreground",
687
- "hover:not-disabled:tw-bg-primary/10",
688
- "hover:not-disabled:tw-text-primary",
689
- "hover:not-disabled:tw-border-primary/10",
690
- "focus-visible:tw-ring-ring/50"
581
+ "tw:bg-transparent",
582
+ "tw:text-foreground",
583
+ "tw:hover:not-disabled:bg-primary/10",
584
+ "tw:hover:not-disabled:text-primary",
585
+ "tw:hover:not-disabled:border-primary/10",
586
+ "tw:focus-visible:ring-ring/50"
691
587
  ],
692
588
  // should be called "link" by Figma
693
589
  inline: [
694
- "tw-bg-transparent",
695
- "tw-text-primary",
696
- "hover:tw-underline",
697
- "hover:active:tw-bg-transparent",
698
- "focus-visible:tw-ring-ring/50"
590
+ "tw:bg-transparent",
591
+ "tw:text-primary",
592
+ "tw:hover:underline",
593
+ "tw:hover:active:bg-transparent",
594
+ "tw:focus-visible:ring-ring/50"
699
595
  ]
700
596
  },
701
597
  size: {
702
598
  // should be called "default" by Figma
703
- medium: ["tw-max-h-9", "tw-py-2", "tw-px-4", "tw-text-sm"],
599
+ medium: ["tw:max-h-9", "tw:py-2", "tw:px-4", "tw:text-sm"],
704
600
  // should be called "small" by Figma
705
- small: ["tw-max-h-8", "tw-py-2", "tw-px-3", "tw-text-xs"],
601
+ small: ["tw:max-h-8", "tw:py-2", "tw:px-3", "tw:text-xs"],
706
602
  // should be called "large" by Figma
707
- large: ["tw-max-h-10", "tw-py-2.5", "tw-px-6", "tw-text-sm"],
708
- "icon-lg": ["tw-size-10"],
709
- icon: ["tw-size-9"],
710
- "icon-sm": ["tw-size-8"],
603
+ large: ["tw:max-h-10", "tw:py-2.5", "tw:px-6", "tw:text-sm"],
604
+ "icon-lg": ["tw:size-10"],
605
+ icon: ["tw:size-9"],
606
+ "icon-sm": ["tw:size-8"],
711
607
  // unsupported in ARGO, remove when old design is gone
712
608
  "icon-xs": [],
713
609
  "icon-2xs": [],
@@ -755,13 +651,13 @@ var Button = ({
755
651
  onClick: handleClick,
756
652
  className: cn(classNames),
757
653
  children: [
758
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(icons_exports.Loader2, { className: "tw-size-4 tw-shrink-0 tw-animate-spin" }),
654
+ isLoading && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Loader2, { className: "tw:size-4 tw:shrink-0 tw:animate-spin" }),
759
655
  /* @__PURE__ */ jsxRuntime.jsx(reactSlot.Slottable, { children: isLoading && isIconOnly ? null : children })
760
656
  ]
761
657
  }
762
658
  );
763
659
  };
764
- var Clipboard = ({
660
+ var Clipboard2 = ({
765
661
  ref,
766
662
  text: textProp,
767
663
  children,
@@ -786,6 +682,7 @@ var Clipboard = ({
786
682
  }
787
683
  };
788
684
  const handleOnClick = (event) => {
685
+ setIsTooltipOpen(true);
789
686
  if (text && state === "ready") void copy(text);
790
687
  onClick?.(event);
791
688
  };
@@ -800,6 +697,7 @@ var Clipboard = ({
800
697
  return tooltip;
801
698
  })();
802
699
  const tooltipVariant = state === "ready" && !!text ? tooltipVariantProp : "action";
700
+ const hasTooltipContent = tooltipContent !== null && tooltipContent !== void 0;
803
701
  return /* @__PURE__ */ jsxRuntime.jsxs(Tooltip.Root, { open: isTooltipOpen, onOpenChange: handleOnOpenChange, children: [
804
702
  /* @__PURE__ */ jsxRuntime.jsx(
805
703
  Tooltip.Trigger,
@@ -808,12 +706,12 @@ var Clipboard = ({
808
706
  asChild,
809
707
  keepOpenOnClick: true,
810
708
  onClick: handleOnClick,
811
- className: cn("tw-cursor-pointer", className),
709
+ className: cn("tw:cursor-pointer", className),
812
710
  ref,
813
711
  children: children ?? text
814
712
  }
815
713
  ),
816
- /* @__PURE__ */ jsxRuntime.jsx(
714
+ hasTooltipContent && /* @__PURE__ */ jsxRuntime.jsx(
817
715
  Tooltip.Content,
818
716
  {
819
717
  keepOpenOnPointerDownOutside: true,
@@ -824,7 +722,7 @@ var Clipboard = ({
824
722
  )
825
723
  ] });
826
724
  };
827
- var DEFAULT_ICON = /* @__PURE__ */ jsxRuntime.jsx(icons_exports.Copy, {});
725
+ var DEFAULT_ICON = /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Copy, {});
828
726
  var DEFAULT_ARIA_LABEL = "Copy";
829
727
  var ClipboardButton = ({
830
728
  // clipboard props
@@ -841,7 +739,7 @@ var ClipboardButton = ({
841
739
  const defaultAriaLabel = typeof tooltip === "string" && tooltip.trim() ? tooltip : DEFAULT_ARIA_LABEL;
842
740
  const ariaLabel = rest["aria-label"] ?? (children == null ? defaultAriaLabel : void 0);
843
741
  return /* @__PURE__ */ jsxRuntime.jsx(
844
- Clipboard,
742
+ Clipboard2,
845
743
  {
846
744
  asChild: true,
847
745
  tooltip,
@@ -857,13 +755,248 @@ var ClipboardButton = ({
857
755
  };
858
756
  var ButtonToolbar = ({ value, children }) => {
859
757
  if (!value && !children) return null;
860
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tw-pointer-events-auto tw-ml-auto tw-mr-4 tw-flex tw-w-fit tw-gap-1 tw-overflow-visible tw-rounded-lg tw-border tw-border-solid tw-border-border !tw-bg-background tw-p-[3px] tw-shadow", children: [
758
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tw:pointer-events-auto tw:ml-auto tw:mr-4 tw:flex tw:w-fit tw:gap-1 tw:overflow-visible tw:rounded-lg tw:border tw:border-solid tw:border-border tw:!bg-background tw:p-[3px] tw:shadow", children: [
861
759
  !!value && /* @__PURE__ */ jsxRuntime.jsx(ClipboardButton, { size: "icon-sm", variant: "invisible", text: value }),
862
760
  children
863
761
  ] });
864
762
  };
763
+ var COMMANDS = [
764
+ "run-operation",
765
+ "run",
766
+ "test",
767
+ "seed",
768
+ "snapshot",
769
+ "list",
770
+ "ls",
771
+ "compile",
772
+ "build",
773
+ "deps",
774
+ "docs",
775
+ "source"
776
+ ];
777
+ var SUBCOMMANDS = { docs: ["generate"], source: ["freshness"] };
778
+ var ARGUMENTS = ["--select", "--exclude", "--selector", "--defer", "--resource-type", "-s"];
779
+ var SELECTORS = ["--select", "--exclude", "-s"];
780
+ var METHODS = [
781
+ "path:",
782
+ "source:",
783
+ "tag:",
784
+ "package:",
785
+ "config:",
786
+ "test_type:",
787
+ "test_name:",
788
+ "state:",
789
+ "exposure:",
790
+ "metric:",
791
+ "result:",
792
+ "source_status:",
793
+ "column_name:"
794
+ ];
795
+ var FLAGS = [
796
+ "--fail-fast",
797
+ "--warn-error",
798
+ "--favor-state",
799
+ "--vars",
800
+ "--models",
801
+ "--threads",
802
+ "--profiles-dir",
803
+ "--profile",
804
+ "--full-refresh"
805
+ ];
806
+ var COMMAND_PHRASES = COMMANDS.flatMap((command) => {
807
+ const subcommands = SUBCOMMANDS[command];
808
+ return subcommands ? subcommands.map((subcommand) => `${command} ${subcommand}`) : [command];
809
+ });
810
+ var alternation = (list) => [...list].sort((a, b) => b.length - a.length).join("|");
811
+ var word = (list) => new RegExp(`^\\s+(?:${alternation(list)})\\b`, "i");
812
+ var prefix = (list) => new RegExp(`^\\s+(?:${alternation(list)})`, "i");
813
+ var WORD = /[\w:-]*$/;
814
+ var asOptions = (list, type) => list.map((label) => ({ label, type }));
815
+ var DBT = [{ label: "dbt", type: "keyword" }];
816
+ var COMMAND_OPTIONS = asOptions(COMMANDS, "keyword");
817
+ var SUBCOMMAND_OPTIONS = Object.fromEntries(
818
+ Object.entries(SUBCOMMANDS).map(([command, subcommands]) => [
819
+ command,
820
+ asOptions(subcommands, "keyword")
821
+ ])
822
+ );
823
+ var ARGUMENT_OPTIONS = asOptions(ARGUMENTS, "variable");
824
+ var FLAG_OPTIONS = asOptions(FLAGS, "constant");
825
+ var METHOD_OPTIONS = asOptions(METHODS, "property");
826
+ var optionsAfter = (words) => {
827
+ const [step, command, ...rest] = words;
828
+ if (step === void 0) return DBT;
829
+ if (step.toLowerCase() !== "dbt") return [];
830
+ if (command === void 0) return COMMAND_OPTIONS;
831
+ const subcommands = SUBCOMMAND_OPTIONS[command.toLowerCase()];
832
+ if (subcommands && rest.length === 0) return subcommands;
833
+ const lastArgument = rest.filter((it) => it.startsWith("-")).at(-1);
834
+ const selecting = lastArgument !== void 0 && SELECTORS.includes(lastArgument.toLowerCase());
835
+ return selecting ? [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS, ...METHOD_OPTIONS] : [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS];
836
+ };
837
+ var complete = (context) => {
838
+ const typed = context.matchBefore(WORD);
839
+ if (!typed?.text && !context.explicit) return null;
840
+ const from = typed?.from ?? context.pos;
841
+ const line = context.state.doc.lineAt(from);
842
+ const options = optionsAfter(
843
+ line.text.slice(0, from - line.from).split(/\s+/).filter(Boolean)
844
+ );
845
+ return options.length > 0 ? { from, options, validFor: WORD } : null;
846
+ };
847
+ var dbt = simpleMode.simpleMode({
848
+ languageData: {
849
+ // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.
850
+ commentTokens: { line: "--", block: { open: "/*", close: "*/" } },
851
+ autocomplete: complete
852
+ },
853
+ start: [
854
+ { regex: /"(?:[^\\]|\\.)*?(?:"|$)/, token: "string" },
855
+ // Word-bounded, so `dbtX` is not a dbt step whose first word happens to
856
+ // colour — the same thing the completion source asks of it.
857
+ { regex: /dbt\b/, token: "keyword", sol: true },
858
+ { regex: word(COMMAND_PHRASES), token: "keyword" },
859
+ { regex: word(ARGUMENTS), token: "variableName" },
860
+ { regex: prefix(METHODS), token: "propertyName" },
861
+ { regex: prefix(FLAGS), token: "attributeName" },
862
+ { regex: /(?:@|\*|,|\+\d+|\d+\+|\+)/, token: "operator" },
863
+ { regex: /'.*'/, token: "string" },
864
+ { regex: /true|false/, token: "atom" }
865
+ ]
866
+ });
867
+
868
+ // src/components/CodeEditor/modes/jsonnet.ts
869
+ var COMMENT_END = /^\*\//;
870
+ var COMMENT_START = /^\/\/|^#/;
871
+ var C_COMMENT_START = /^\/\*/;
872
+ var TEXT_BLOCK = /^\|\|\|/;
873
+ var TEXT_BLOCK_END = /^\s*\|\|\|/;
874
+ var RAW_DOUBLE = /^""/;
875
+ var RAW_SINGLE = /^''/;
876
+ var CLOSE_DOUBLE = /^"/;
877
+ var CLOSE_SINGLE = /^'/;
878
+ var ESCAPE = /^\\[\\"'/bfnrt0]/;
879
+ var UNICODE_ESCAPE = /^\\u[0-9a-fA-F]{4}/;
880
+ var BACKSLASH = /^\\/;
881
+ var IMPORT = /^import(?:str)?\s*(@?)(["'])/;
882
+ var QUOTE = /^(@?)(["'])/;
883
+ var ROOT = /^\$/;
884
+ var NUMBER = /^(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i;
885
+ var OPERATOR = /^[-+/*=<>!&~^|$%]+/;
886
+ var IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*/;
887
+ var KEYWORDS = {
888
+ local: "keyword",
889
+ self: "keyword",
890
+ super: "keyword",
891
+ assert: "keyword",
892
+ function: "keyword",
893
+ if: "keyword",
894
+ then: "keyword",
895
+ else: "keyword",
896
+ for: "keyword",
897
+ in: "keyword",
898
+ tailstrict: "keyword",
899
+ error: "keyword",
900
+ true: "atom",
901
+ false: "atom",
902
+ null: "atom"
903
+ };
904
+ var jsonnet = {
905
+ name: "jsonnet",
906
+ // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.
907
+ languageData: { commentTokens: { line: "//", block: { open: "/*", close: "*/" } } },
908
+ startState: () => ({
909
+ cComment: false,
910
+ textBlock: false,
911
+ textBlockIndent: null,
912
+ string: false,
913
+ importString: false,
914
+ stringSingle: false,
915
+ stringRaw: false
916
+ }),
917
+ token: (stream, state) => {
918
+ if (state.cComment) {
919
+ if (stream.match(COMMENT_END)) {
920
+ state.cComment = false;
921
+ return "comment";
922
+ }
923
+ stream.next();
924
+ return "comment";
925
+ }
926
+ if (state.textBlock) {
927
+ if (state.textBlockIndent == null) {
928
+ if (stream.match(TEXT_BLOCK_END)) {
929
+ state.textBlock = false;
930
+ return "string";
931
+ }
932
+ state.textBlockIndent = stream.indentation();
933
+ }
934
+ if (stream.indentation() >= state.textBlockIndent) {
935
+ stream.skipToEnd();
936
+ return "string";
937
+ }
938
+ if (stream.match(TEXT_BLOCK_END)) {
939
+ state.textBlock = false;
940
+ return "string";
941
+ }
942
+ stream.next();
943
+ return "invalid";
944
+ }
945
+ if (state.string || state.importString) {
946
+ const style = state.string ? "string" : "meta";
947
+ if (state.stringRaw) {
948
+ if (stream.match(state.stringSingle ? RAW_SINGLE : RAW_DOUBLE)) return "escape";
949
+ } else {
950
+ if (stream.match(ESCAPE)) return "escape";
951
+ if (stream.match(UNICODE_ESCAPE)) return "escape";
952
+ if (stream.match(BACKSLASH)) return "invalid";
953
+ }
954
+ if (stream.match(state.stringSingle ? CLOSE_SINGLE : CLOSE_DOUBLE)) {
955
+ state.string = false;
956
+ state.importString = false;
957
+ return style;
958
+ }
959
+ stream.next();
960
+ return style;
961
+ }
962
+ if (stream.match(COMMENT_START)) {
963
+ stream.skipToEnd();
964
+ return "comment";
965
+ }
966
+ if (stream.match(C_COMMENT_START)) {
967
+ state.cComment = true;
968
+ return "comment";
969
+ }
970
+ const imported = stream.match(IMPORT);
971
+ if (Array.isArray(imported)) {
972
+ state.importString = true;
973
+ state.stringRaw = imported[1] === "@";
974
+ state.stringSingle = imported[2] === "'";
975
+ return "meta";
976
+ }
977
+ const quoted = stream.match(QUOTE);
978
+ if (Array.isArray(quoted)) {
979
+ state.string = true;
980
+ state.stringRaw = quoted[1] === "@";
981
+ state.stringSingle = quoted[2] === "'";
982
+ return "string";
983
+ }
984
+ if (stream.match(TEXT_BLOCK)) {
985
+ state.textBlock = true;
986
+ state.textBlockIndent = null;
987
+ return "string";
988
+ }
989
+ if (stream.match(ROOT)) return "keyword";
990
+ if (stream.match(NUMBER)) return "number";
991
+ if (stream.match(OPERATOR)) return "operator";
992
+ const identifier = stream.match(IDENTIFIER);
993
+ if (Array.isArray(identifier)) return KEYWORDS[identifier[0]] ?? null;
994
+ stream.next();
995
+ return null;
996
+ }
997
+ };
865
998
  var resolveToken = (token, fallbackChannels, alpha) => {
866
- const channels = typeof document === "undefined" ? fallbackChannels : getComputedStyle(document.documentElement).getPropertyValue(`--color-${token}`).trim() || fallbackChannels;
999
+ const channels = typeof document === "undefined" ? fallbackChannels : getComputedStyle(document.documentElement).getPropertyValue(`--${token}`).trim() || fallbackChannels;
867
1000
  return alpha === void 0 ? `rgb(${channels})` : `rgb(${channels} / ${alpha})`;
868
1001
  };
869
1002
  var SSR_SIGNAL = "ssr";
@@ -883,12 +1016,38 @@ var subscribeThemeSignal = (onChange) => {
883
1016
  return () => observer.disconnect();
884
1017
  };
885
1018
  var useThemeSignal = () => react.useSyncExternalStore(subscribeThemeSignal, readThemeSignal, () => SSR_SIGNAL);
886
- var useThemedExtension = (build, deps = []) => {
1019
+ var themeCache = /* @__PURE__ */ new Map();
1020
+ var useThemedExtension = (cacheKey, build) => {
887
1021
  const themeSignal = useThemeSignal();
888
- return react.useMemo(build, [themeSignal, ...deps]);
1022
+ const key = `${themeSignal} ${cacheKey}`;
1023
+ let cached = themeCache.get(key);
1024
+ if (!cached) {
1025
+ cached = build();
1026
+ themeCache.set(key, cached);
1027
+ }
1028
+ return cached;
889
1029
  };
890
1030
 
891
1031
  // src/components/CodeEditor/helpers.ts
1032
+ var LANGUAGE_MODES = [
1033
+ "application/json",
1034
+ "text/plain",
1035
+ "text/x-python",
1036
+ "text/x-sql",
1037
+ "text/x-mysql",
1038
+ "text/x-pgsql",
1039
+ "text/x-mssql",
1040
+ "text/x-sfsql",
1041
+ "text/x-plsql",
1042
+ "text/x-rsrc",
1043
+ "text/x-sh",
1044
+ "text/x-toml",
1045
+ "text/jsonnet",
1046
+ "text/x-dbt",
1047
+ "text/javascript",
1048
+ "text/typescript"
1049
+ ];
1050
+ var isLanguageMode = (mode) => LANGUAGE_MODES.includes(mode);
892
1051
  var buildBaseThemeStyles = () => ({
893
1052
  "*": { lineHeight: "20px" },
894
1053
  "*::selection": {
@@ -929,7 +1088,27 @@ var buildBaseThemeStyles = () => ({
929
1088
  ".cm-changeGutter": { position: "absolute", zIndex: -1, width: "100%", paddingLeft: 0 },
930
1089
  '&[class*="cm-merge-"] .cm-changedLine,&[class*="cm-merge-"] .cm-line, &[class*="cm-merge-"] .cm-deletedChunk': { paddingLeft: 0 }
931
1090
  });
932
- var BASIS_SETUP = { drawSelection: false };
1091
+ var ALWAYS_OFF = {
1092
+ drawSelection: false,
1093
+ foldGutter: false,
1094
+ foldKeymap: false,
1095
+ highlightActiveLine: false,
1096
+ highlightActiveLineGutter: false
1097
+ };
1098
+ var buildBasicSetup = (readOnly) => ({
1099
+ ...ALWAYS_OFF,
1100
+ ...readOnly ? {
1101
+ history: false,
1102
+ historyKeymap: false,
1103
+ closeBrackets: false,
1104
+ closeBracketsKeymap: false,
1105
+ lintKeymap: false,
1106
+ indentOnInput: false,
1107
+ rectangularSelection: false,
1108
+ dropCursor: false,
1109
+ highlightSelectionMatches: false
1110
+ } : null
1111
+ });
933
1112
  var buildCustomTheme = () => codemirrorThemeGithub.githubLightInit({
934
1113
  settings: {
935
1114
  fontFamily: `'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New'`,
@@ -942,37 +1121,175 @@ var buildCustomTheme = () => codemirrorThemeGithub.githubLightInit({
942
1121
  selection: resolveToken("primary", "31 143 255")
943
1122
  }
944
1123
  });
1124
+ var sfsqlWithLanguageData = {
1125
+ ...codemirrorLangSfsql.sfsql,
1126
+ languageData: {
1127
+ ...codemirrorLangSfsql.sfsql.languageData,
1128
+ // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.
1129
+ commentTokens: { line: "--", block: { open: "/*", close: "*/" } },
1130
+ autocomplete: autocomplete.completeFromList(
1131
+ Object.keys(codemirrorLangSfsql.modeSpec.keywords).map((label) => ({
1132
+ label: label.toUpperCase(),
1133
+ type: "keyword"
1134
+ }))
1135
+ )
1136
+ }
1137
+ };
945
1138
  var getLanguageMode = (mode) => {
946
1139
  switch (mode) {
1140
+ case void 0:
1141
+ case "application/json":
1142
+ return langJson.json();
947
1143
  case "text/x-python":
948
1144
  return langPython.python();
949
1145
  case "text/x-sql":
950
1146
  return langSql.sql({ upperCaseKeywords: true });
1147
+ case "text/x-mysql":
1148
+ return langSql.sql({ upperCaseKeywords: true, dialect: langSql.MySQL });
1149
+ case "text/x-pgsql":
1150
+ return langSql.sql({ upperCaseKeywords: true, dialect: langSql.PostgreSQL });
1151
+ case "text/x-mssql":
1152
+ return langSql.sql({ upperCaseKeywords: true, dialect: langSql.MSSQL });
951
1153
  case "text/x-sfsql":
952
- return language.StreamLanguage.define(codemirrorLangSfsql.sfsql);
1154
+ return language.StreamLanguage.define(sfsqlWithLanguageData);
953
1155
  case "text/x-plsql":
954
1156
  return langSql.sql({ upperCaseKeywords: true, dialect: langSql.PLSQL });
955
1157
  case "text/x-rsrc":
956
1158
  return language.StreamLanguage.define(r.r);
957
1159
  case "text/x-sh":
958
1160
  return language.StreamLanguage.define(shell.shell);
1161
+ case "text/x-toml":
1162
+ return language.StreamLanguage.define(toml.toml);
1163
+ case "text/jsonnet":
1164
+ return language.StreamLanguage.define(jsonnet);
1165
+ case "text/x-dbt":
1166
+ return language.StreamLanguage.define(dbt);
959
1167
  case "text/javascript":
960
1168
  return langJavascript.javascript({ jsx: true });
961
1169
  case "text/typescript":
962
1170
  return langJavascript.javascript({ jsx: true, typescript: true });
1171
+ // No language — `text/plain` lands here, and so does any mode added to
1172
+ // LANGUAGE_MODES without an arm above. Unstyled text is the safe degradation;
1173
+ // a `json()` default would colour unrelated content as if it were JSON.
963
1174
  default:
964
- return langJson.json();
1175
+ return [];
965
1176
  }
966
1177
  };
967
1178
  var shouldLintJson = (mode, readOnly) => mode === "application/json" && !readOnly;
968
- var KbdSeparator = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...props, className: cn("tw-text-xs tw-text-muted-foreground", className) });
1179
+ var setSearchEffect = state.StateEffect.define();
1180
+ function findMatches(doc, query) {
1181
+ if (!query) return [];
1182
+ const text = doc.toString();
1183
+ try {
1184
+ const regex = new RegExp(escapeStringRegexp(query), "gi");
1185
+ return Array.from(text.matchAll(regex)).map((match, index) => {
1186
+ const from = match.index;
1187
+ const to = from + match[0].length;
1188
+ return { from, to, text: match[0], localIndex: index };
1189
+ });
1190
+ } catch (e) {
1191
+ console.warn("Invalid search regex:", e);
1192
+ return [];
1193
+ }
1194
+ }
1195
+ function createDecorations(matches, selectedLocalIndex) {
1196
+ const decorations = matches.map((match) => {
1197
+ const isSelected = match.localIndex === selectedLocalIndex;
1198
+ const decoration = view.Decoration.mark({
1199
+ class: isSelected ? "cm-searchMatch-selected" : "cm-searchMatch"
1200
+ });
1201
+ return decoration.range(match.from, match.to);
1202
+ });
1203
+ return view.Decoration.set(decorations, true);
1204
+ }
1205
+ var searchField = state.StateField.define({
1206
+ create() {
1207
+ return {
1208
+ query: "",
1209
+ selectedMatchIndex: void 0,
1210
+ matches: [],
1211
+ decorations: view.Decoration.none
1212
+ };
1213
+ },
1214
+ update(state, tr) {
1215
+ let newState = state;
1216
+ for (const effect of tr.effects) {
1217
+ if (!effect.is(setSearchEffect)) {
1218
+ continue;
1219
+ }
1220
+ const { query, selectedMatchIndex } = effect.value;
1221
+ const matches = findMatches(tr.state.doc, query);
1222
+ const decorations = createDecorations(matches, selectedMatchIndex);
1223
+ newState = {
1224
+ query,
1225
+ selectedMatchIndex,
1226
+ matches,
1227
+ decorations
1228
+ };
1229
+ }
1230
+ if (tr.docChanged && newState.query) {
1231
+ const matches = findMatches(tr.state.doc, newState.query);
1232
+ const decorations = createDecorations(matches, newState.selectedMatchIndex);
1233
+ newState = {
1234
+ ...newState,
1235
+ matches,
1236
+ decorations
1237
+ };
1238
+ }
1239
+ return newState;
1240
+ },
1241
+ provide: (field) => view.EditorView.decorations.from(field, (state) => state.decorations)
1242
+ });
1243
+ var searchViewPlugin = view.ViewPlugin.fromClass(
1244
+ class {
1245
+ lastSelectedIndex;
1246
+ update(update) {
1247
+ const state = update.state.field(searchField);
1248
+ if (state.selectedMatchIndex !== void 0 && state.selectedMatchIndex !== this.lastSelectedIndex) {
1249
+ const match = state.matches[state.selectedMatchIndex];
1250
+ if (match) {
1251
+ requestAnimationFrame(() => {
1252
+ update.view.dispatch({
1253
+ effects: view.EditorView.scrollIntoView(match.from, { y: "center" })
1254
+ });
1255
+ });
1256
+ }
1257
+ this.lastSelectedIndex = state.selectedMatchIndex;
1258
+ }
1259
+ if (state.selectedMatchIndex === void 0) {
1260
+ this.lastSelectedIndex = void 0;
1261
+ }
1262
+ }
1263
+ }
1264
+ );
1265
+ var searchTheme = view.EditorView.baseTheme({
1266
+ ".cm-searchMatch": {
1267
+ backgroundColor: colors__default.default.blue[100]
1268
+ },
1269
+ ".cm-searchMatch > span": {
1270
+ color: `${colors__default.default.blue[600]} !important`
1271
+ },
1272
+ ".cm-searchMatch-selected": {
1273
+ backgroundColor: colors__default.default.blue[600]
1274
+ },
1275
+ ".cm-searchMatch-selected > span": {
1276
+ color: `${colors__default.default.white} !important`
1277
+ }
1278
+ });
1279
+ function searchExtension() {
1280
+ return [searchField, searchViewPlugin, searchTheme];
1281
+ }
1282
+ function updateSearch(view, query, selectedMatchIndex) {
1283
+ view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });
1284
+ }
1285
+ var KbdSeparator = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx("span", { ...props, className: cn("tw:text-xs tw:text-muted-foreground", className) });
969
1286
  var KbdGroup = ({ ref, className, children, separator, ...props }) => {
970
1287
  return /* @__PURE__ */ jsxRuntime.jsx(
971
1288
  "kbd",
972
1289
  {
973
1290
  ...props,
974
1291
  ref,
975
- className: cn("tw-inline-flex", "tw-items-center", "tw-gap-1", className),
1292
+ className: cn("tw:inline-flex", "tw:items-center", "tw:gap-1", className),
976
1293
  children: separator ? (
977
1294
  // oxlint-disable-next-line react-x/no-children-to-array
978
1295
  react.Children.toArray(children).map((child, index) => (
@@ -990,22 +1307,22 @@ var kbdVariants = classVarianceAuthority.cva(
990
1307
  [
991
1308
  "tailwindcss-preflight",
992
1309
  // style
993
- "tw-pointer-events-none",
994
- "tw-w-fit",
995
- "tw-h-5",
996
- "tw-min-w-5",
1310
+ "tw:pointer-events-none",
1311
+ "tw:w-fit",
1312
+ "tw:h-5",
1313
+ "tw:min-w-5",
997
1314
  // layout
998
- "tw-inline-flex",
999
- "tw-items-center",
1000
- "tw-justify-center",
1001
- "tw-gap-1",
1002
- "tw-shrink-0",
1315
+ "tw:inline-flex",
1316
+ "tw:items-center",
1317
+ "tw:justify-center",
1318
+ "tw:gap-1",
1319
+ "tw:shrink-0",
1003
1320
  // spacing
1004
- "tw-px-1",
1005
- '[&_svg:not([class*="size-"])]:tw-size-2.5',
1006
- "tw-text-xs",
1007
- "tw-font-medium",
1008
- "tw-rounded"
1321
+ "tw:px-1",
1322
+ 'tw:[&_svg:not([class*="size-"])]:size-2.5',
1323
+ "tw:text-xs",
1324
+ "tw:font-medium",
1325
+ "tw:rounded"
1009
1326
  ],
1010
1327
  {
1011
1328
  defaultVariants: {
@@ -1013,8 +1330,8 @@ var kbdVariants = classVarianceAuthority.cva(
1013
1330
  },
1014
1331
  variants: {
1015
1332
  variant: {
1016
- default: "tw-bg-muted tw-text-muted-foreground",
1017
- primary: "tw-bg-white/20 tw-text-white"
1333
+ default: "tw:bg-muted tw:text-muted-foreground",
1334
+ primary: "tw:bg-white/20 tw:text-white"
1018
1335
  }
1019
1336
  }
1020
1337
  }
@@ -1024,11 +1341,78 @@ Kbd.Group = KbdGroup;
1024
1341
  Kbd.Separator = KbdSeparator;
1025
1342
  var ToggleComponentHelp = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1026
1343
  "Use ",
1027
- /* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "Ctrl+/" }),
1028
- " or ",
1029
- /* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "Command+/" }),
1344
+ /* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: isMac ? "Command+/" : "Ctrl+/" }),
1030
1345
  " to toggle comments."
1031
1346
  ] });
1347
+ var establishesFixedContainingBlock = (style) => style.transform !== "none" || style.translate !== "none" || style.rotate !== "none" || style.scale !== "none" || style.perspective !== "none" || style.filter !== "none" || style.backdropFilter !== "none" || /\b(paint|layout|strict|content)\b/.test(style.contain) || /\b(transform|perspective|filter|contain)\b/.test(style.willChange);
1348
+ var crops = (style) => style.overflowX !== "visible" || style.overflowY !== "visible" || style.maskImage !== "none" || style.contentVisibility !== "visible" || /\b(paint|strict|content)\b/.test(style.contain);
1349
+ var findTooltipHost = (from) => {
1350
+ let outermostCropper = null;
1351
+ for (let node = from.parentElement; node && node !== document.body; node = node.parentElement) {
1352
+ const style = getComputedStyle(node);
1353
+ if (crops(style)) {
1354
+ outermostCropper = node;
1355
+ } else if (establishesFixedContainingBlock(style)) {
1356
+ return outermostCropper?.parentElement ?? node;
1357
+ }
1358
+ }
1359
+ return outermostCropper?.parentElement ?? null;
1360
+ };
1361
+ var tooltipsExtension = () => {
1362
+ const layer = new state.Compartment();
1363
+ return [
1364
+ layer.of(view.tooltips()),
1365
+ view.ViewPlugin.define((view$1) => {
1366
+ const scheduled = setTimeout(() => {
1367
+ if (!view$1.dom.isConnected) return;
1368
+ const parent = findTooltipHost(view$1.dom);
1369
+ if (parent) view$1.dispatch({ effects: layer.reconfigure(view.tooltips({ parent })) });
1370
+ });
1371
+ return { destroy: () => clearTimeout(scheduled) };
1372
+ })
1373
+ ];
1374
+ };
1375
+ var useTooltipsExtension = () => react.useMemo(tooltipsExtension, []);
1376
+
1377
+ // src/components/CodeEditor/variableCompletion.ts
1378
+ var BOOST = 2e3;
1379
+ var NAME = String.raw`[\w-]*`;
1380
+ var AT_CARET = new RegExp(String.raw`(?:\{{1,2} ?)?${NAME}$`);
1381
+ var NAME_AT_END = new RegExp(`${NAME}$`);
1382
+ var OPENING = /\{{1,2} ?$/;
1383
+ var CLOSING = /^ ?\}{1,2}/;
1384
+ var completeVariables = (variables = []) => {
1385
+ if (variables.length === 0) return () => null;
1386
+ const options = variables.map(({ name, value }) => ({
1387
+ // The bare name: `SqlEditor` filters prefix-only while `CodeEditor` filters
1388
+ // fuzzily, and this is the only spelling both accept whether or not the caret
1389
+ // has typed the braces. The braces are `displayLabel`, which is what renders.
1390
+ label: name,
1391
+ displayLabel: `{{${name}}}`,
1392
+ detail: value,
1393
+ type: "variable",
1394
+ boost: BOOST,
1395
+ apply: (view, completion, from, to) => {
1396
+ const { doc } = view.state;
1397
+ const line = doc.lineAt(from);
1398
+ const insert = `{{${completion.label}}}`;
1399
+ const opening = OPENING.exec(doc.sliceString(line.from, from));
1400
+ const closing = CLOSING.exec(doc.sliceString(to, line.to));
1401
+ const start = opening ? from - opening[0].length : from;
1402
+ const end = closing ? to + closing[0].length : to;
1403
+ view.dispatch({
1404
+ changes: { from: start, to: end, insert },
1405
+ selection: { anchor: start + insert.length }
1406
+ });
1407
+ }
1408
+ }));
1409
+ return (context) => {
1410
+ const match = context.matchBefore(AT_CARET);
1411
+ if (!match?.text) return null;
1412
+ const [name = ""] = NAME_AT_END.exec(match.text) ?? [];
1413
+ return { from: match.to - name.length, options };
1414
+ };
1415
+ };
1032
1416
  var emptyArray = [];
1033
1417
  var emptyObject = {};
1034
1418
  var CodeEditor = ({
@@ -1037,45 +1421,96 @@ var CodeEditor = ({
1037
1421
  onChange,
1038
1422
  mode = "application/json",
1039
1423
  placeholder = "",
1424
+ ariaLabel,
1425
+ searchQuery,
1426
+ searchMatchIndex,
1040
1427
  readOnly = false,
1041
1428
  autocompletions = emptyArray,
1429
+ completionSource,
1430
+ variables,
1042
1431
  extraKeys = emptyObject,
1043
1432
  withToggleCommentHint = false,
1044
1433
  withAutofocus = false,
1045
1434
  withLineNumbers = true,
1046
1435
  withLineWrapping = true,
1047
1436
  withCollapseUnchanged = false,
1048
- withCopyButton = true,
1437
+ withCopyButton = false,
1049
1438
  completeAny = false,
1050
1439
  help = null,
1051
1440
  helpPostfix = null,
1052
1441
  renderAdditionalButtons,
1053
1442
  className
1054
1443
  }) => {
1055
- const customTheme = useThemedExtension(buildCustomTheme);
1056
- const baseTheme = useThemedExtension(() => view.EditorView.theme(buildBaseThemeStyles()));
1444
+ const handleChange = useStableCallback((next) => onChange?.(next));
1445
+ const withSearch = searchQuery !== void 0;
1446
+ const editorRef = react.useRef(null);
1447
+ react.useEffect(() => {
1448
+ const view = editorRef.current?.view;
1449
+ if (view && withSearch) updateSearch(view, searchQuery, searchMatchIndex);
1450
+ }, [withSearch, searchQuery, searchMatchIndex]);
1451
+ const handleCreateEditor = useStableCallback((view) => {
1452
+ if (searchQuery) updateSearch(view, searchQuery, searchMatchIndex);
1453
+ });
1454
+ const extraKeysRef = react.useRef(extraKeys);
1455
+ react.useLayoutEffect(() => {
1456
+ extraKeysRef.current = extraKeys;
1457
+ });
1458
+ const boundKeysSignature = Object.keys(extraKeys).join("\n");
1459
+ const boundKeys = react.useMemo(
1460
+ () => boundKeysSignature.split("\n").filter(Boolean),
1461
+ [boundKeysSignature]
1462
+ );
1463
+ const tooltipLayer = useTooltipsExtension();
1464
+ const variableCompletion = react.useMemo(() => completeVariables(variables), [variables]);
1465
+ const customTheme = useThemedExtension("editor:syntax", buildCustomTheme);
1466
+ const baseTheme = useThemedExtension(
1467
+ "code-editor:chrome",
1468
+ () => view.EditorView.theme(buildBaseThemeStyles())
1469
+ );
1057
1470
  const commonExtensions = react.useMemo(() => {
1058
1471
  return [
1059
1472
  getLanguageMode(mode),
1060
- shouldLintJson(mode, readOnly) && lint.linter(langJson.jsonParseLinter()),
1473
+ shouldLintJson(mode, readOnly) ? lint.linter(langJson.jsonParseLinter()) : [],
1061
1474
  withLineWrapping ? view.EditorView.lineWrapping : [],
1062
1475
  CodeMirror.EditorState.languageData.of(() => [
1063
- { autocomplete: completeAny ? autocomplete.completeAnyWord : autocompletions }
1476
+ { autocomplete: completionSource ?? (completeAny ? autocomplete.completeAnyWord : autocompletions) }
1064
1477
  ]),
1478
+ CodeMirror.EditorState.languageData.of(() => [{ autocomplete: variableCompletion }]),
1065
1479
  view.keymap.of(
1066
- Object.entries(extraKeys).map(([key, run]) => ({
1480
+ boundKeys.map((key) => ({
1067
1481
  key,
1068
1482
  run: () => {
1069
- if (typeof run === "string") return run;
1070
- run();
1483
+ extraKeysRef.current[key]?.();
1071
1484
  return true;
1072
1485
  }
1073
1486
  }))
1074
1487
  ),
1075
- autocomplete.autocompletion({ activateOnTyping: completeAny }),
1488
+ readOnly ? [] : [
1489
+ // CodeMirror's own default. Gating it on the props hid completions the
1490
+ // *language* supplies — dbt's vocabulary, Snowflake's keywords — behind
1491
+ // a shortcut, and macOS leaves no usable one. With nothing to offer, no
1492
+ // popup opens anyway.
1493
+ autocomplete.autocompletion()
1494
+ ],
1495
+ ariaLabel ? view.EditorView.contentAttributes.of({ "aria-label": ariaLabel }) : [],
1496
+ withSearch ? searchExtension() : [],
1497
+ tooltipLayer,
1076
1498
  baseTheme
1077
- ].filter(Boolean);
1078
- }, [autocompletions, completeAny, extraKeys, mode, readOnly, withLineWrapping, baseTheme]);
1499
+ ];
1500
+ }, [
1501
+ autocompletions,
1502
+ completionSource,
1503
+ variableCompletion,
1504
+ completeAny,
1505
+ boundKeys,
1506
+ mode,
1507
+ readOnly,
1508
+ withLineWrapping,
1509
+ baseTheme,
1510
+ ariaLabel,
1511
+ withSearch,
1512
+ tooltipLayer
1513
+ ]);
1079
1514
  const extensions = react.useMemo(() => {
1080
1515
  return [
1081
1516
  ...commonExtensions,
@@ -1092,18 +1527,23 @@ var CodeEditor = ({
1092
1527
  }, [commonExtensions, placeholder, readOnly, previousValue, withCollapseUnchanged]);
1093
1528
  const config = react.useMemo(() => {
1094
1529
  return {
1095
- ...BASIS_SETUP,
1096
- lineNumbers: withLineNumbers
1530
+ ...buildBasicSetup(readOnly),
1531
+ lineNumbers: withLineNumbers,
1532
+ // Mod-f opens CodeMirror's own panel, which would run a second query and a
1533
+ // second match count over the same document beside the caller's input.
1534
+ ...withSearch ? { searchKeymap: false } : null
1097
1535
  };
1098
- }, [withLineNumbers]);
1536
+ }, [withLineNumbers, readOnly, withSearch]);
1537
+ const additionalButtons = renderAdditionalButtons?.(value);
1538
+ const hasToolbar = withCopyButton && !!value || !!additionalButtons;
1099
1539
  return (
1100
1540
  // oxlint-disable-next-line jsx-a11y/no-static-element-interactions
1101
1541
  /* @__PURE__ */ jsxRuntime.jsxs(
1102
1542
  "div",
1103
1543
  {
1104
1544
  className: cn(
1105
- "tw-relative tw-flex tw-min-h-0 tw-flex-col [&_.cm-mergeViewEditor]:tw-overflow-visible [&_.cm-mergeViewEditors]:tw-h-full [&_.cm-mergeView]:tw-h-full [&_>div]:tw-h-full [&_>div]:tw-overflow-auto [&_>div]:tw-bg-background",
1106
- { "tw-mt-5": !!renderAdditionalButtons },
1545
+ "tw:relative tw:flex tw:min-h-0 tw:flex-col tw:[&_.cm-mergeViewEditor]:overflow-visible tw:[&_.cm-mergeViewEditors]:h-full tw:[&_.cm-mergeView]:h-full tw:[&_>div]:h-full tw:[&_>div]:overflow-auto tw:[&_>div]:bg-background",
1546
+ { "tw:mt-8": hasToolbar },
1107
1547
  className
1108
1548
  ),
1109
1549
  onKeyDown: (event) => {
@@ -1112,19 +1552,21 @@ var CodeEditor = ({
1112
1552
  }
1113
1553
  },
1114
1554
  children: [
1115
- (withCopyButton || renderAdditionalButtons) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-pointer-events-none tw-absolute tw-z-10 tw-flex !tw-h-auto tw-w-full tw-translate-y-[calc(-100%_+_8px)] !tw-overflow-visible !tw-bg-transparent", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ButtonToolbar, { value: withCopyButton ? value : void 0, children: renderAdditionalButtons?.(value) }) }) }),
1555
+ hasToolbar && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw:pointer-events-none tw:absolute tw:z-10 tw:flex tw:!h-auto tw:w-full tw:translate-y-[calc(-100%_+_8px)] tw:!overflow-visible tw:!bg-transparent", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw:flex-1", children: /* @__PURE__ */ jsxRuntime.jsx(ButtonToolbar, { value: withCopyButton ? value : void 0, children: additionalButtons }) }) }),
1116
1556
  /* @__PURE__ */ jsxRuntime.jsx(
1117
1557
  CodeMirror__default.default,
1118
1558
  {
1559
+ ref: editorRef,
1560
+ onCreateEditor: handleCreateEditor,
1119
1561
  theme: customTheme,
1120
1562
  value,
1121
- onChange,
1563
+ onChange: handleChange,
1122
1564
  extensions,
1123
1565
  autoFocus: withAutofocus,
1124
1566
  basicSetup: config
1125
1567
  }
1126
1568
  ),
1127
- !readOnly && (withToggleCommentHint || help || helpPostfix) && /* @__PURE__ */ jsxRuntime.jsxs(HelpBlock, { className: "tw-mt-2 tw-flex tw-flex-wrap tw-gap-1", children: [
1569
+ !readOnly && (withToggleCommentHint || help || helpPostfix) && /* @__PURE__ */ jsxRuntime.jsxs(HelpBlock, { className: "tw:mt-2 tw:flex tw:flex-wrap tw:gap-1", children: [
1128
1570
  help,
1129
1571
  withToggleCommentHint ? /* @__PURE__ */ jsxRuntime.jsx(ToggleComponentHelp, {}) : null,
1130
1572
  helpPostfix
@@ -1438,114 +1880,7 @@ function highlightingExtension(queryParser) {
1438
1880
  function updateHighlighting(view, lines) {
1439
1881
  view.dispatch({ effects: setHighlightedLinesEffect.of(lines ?? null) });
1440
1882
  }
1441
- var setSearchEffect = state.StateEffect.define();
1442
- function findMatches(doc, query) {
1443
- if (!query) return [];
1444
- const text = doc.toString();
1445
- try {
1446
- const regex = new RegExp(escapeStringRegexp(query), "gi");
1447
- return Array.from(text.matchAll(regex)).map((match, index) => {
1448
- const from = match.index;
1449
- const to = from + match[0].length;
1450
- return { from, to, text: match[0], localIndex: index };
1451
- });
1452
- } catch (e) {
1453
- console.warn("Invalid search regex:", e);
1454
- return [];
1455
- }
1456
- }
1457
- function createDecorations(matches, selectedLocalIndex) {
1458
- const decorations = matches.map((match) => {
1459
- const isSelected = match.localIndex === selectedLocalIndex;
1460
- const decoration = view.Decoration.mark({
1461
- class: isSelected ? "cm-searchMatch-selected" : "cm-searchMatch"
1462
- });
1463
- return decoration.range(match.from, match.to);
1464
- });
1465
- return view.Decoration.set(decorations, true);
1466
- }
1467
- var searchField = state.StateField.define({
1468
- create() {
1469
- return {
1470
- query: "",
1471
- selectedMatchIndex: void 0,
1472
- matches: [],
1473
- decorations: view.Decoration.none
1474
- };
1475
- },
1476
- update(state, tr) {
1477
- let newState = state;
1478
- for (const effect of tr.effects) {
1479
- if (!effect.is(setSearchEffect)) {
1480
- continue;
1481
- }
1482
- const { query, selectedMatchIndex } = effect.value;
1483
- const matches = findMatches(tr.state.doc, query);
1484
- const decorations = createDecorations(matches, selectedMatchIndex);
1485
- newState = {
1486
- query,
1487
- selectedMatchIndex,
1488
- matches,
1489
- decorations
1490
- };
1491
- }
1492
- if (tr.docChanged && newState.query) {
1493
- const matches = findMatches(tr.state.doc, newState.query);
1494
- const decorations = createDecorations(matches, newState.selectedMatchIndex);
1495
- newState = {
1496
- ...newState,
1497
- matches,
1498
- decorations
1499
- };
1500
- }
1501
- return newState;
1502
- },
1503
- provide: (field) => view.EditorView.decorations.from(field, (state) => state.decorations)
1504
- });
1505
- var searchViewPlugin = view.ViewPlugin.fromClass(
1506
- class {
1507
- lastSelectedIndex;
1508
- update(update) {
1509
- const state = update.state.field(searchField);
1510
- if (state.selectedMatchIndex !== void 0 && state.selectedMatchIndex !== this.lastSelectedIndex) {
1511
- const match = state.matches[state.selectedMatchIndex];
1512
- if (match) {
1513
- requestAnimationFrame(() => {
1514
- update.view.dispatch({
1515
- effects: view.EditorView.scrollIntoView(match.from, { y: "center" })
1516
- });
1517
- });
1518
- }
1519
- this.lastSelectedIndex = state.selectedMatchIndex;
1520
- }
1521
- if (state.selectedMatchIndex === void 0) {
1522
- this.lastSelectedIndex = void 0;
1523
- }
1524
- }
1525
- }
1526
- );
1527
- var searchTheme = view.EditorView.baseTheme({
1528
- ".cm-searchMatch": {
1529
- backgroundColor: colors__default.default.blue[100]
1530
- },
1531
- ".cm-searchMatch > span": {
1532
- color: `${colors__default.default.blue[600]} !important`
1533
- },
1534
- ".cm-searchMatch-selected": {
1535
- backgroundColor: colors__default.default.blue[600]
1536
- },
1537
- ".cm-searchMatch-selected > span": {
1538
- color: `${colors__default.default.white} !important`
1539
- }
1540
- });
1541
- function searchExtension() {
1542
- return [searchField, searchViewPlugin, searchTheme];
1543
- }
1544
- function updateSearch(view, query, selectedMatchIndex) {
1545
- view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });
1546
- }
1547
- var BASIS_SETUP2 = {
1548
- drawSelection: false,
1883
+ var OWN_KEYMAPS = {
1549
1884
  defaultKeymap: false,
1550
1885
  completionKeymap: false,
1551
1886
  searchKeymap: false
@@ -1610,16 +1945,27 @@ var SqlEditor = ({
1610
1945
  dialect
1611
1946
  }) => {
1612
1947
  const editorRef = react.useRef(null);
1613
- const customTheme = useThemedExtension(buildCustomTheme);
1614
- const themeExtension = useThemedExtension(() => CodeMirror.EditorView.theme(buildTheme()));
1948
+ const tooltipLayer = useTooltipsExtension();
1949
+ const customTheme = useThemedExtension("editor:syntax", buildCustomTheme);
1950
+ const themeExtension = useThemedExtension(
1951
+ "sql-editor:chrome",
1952
+ () => CodeMirror.EditorView.theme(buildTheme())
1953
+ );
1615
1954
  const extensions = react.useMemo(() => {
1616
1955
  const baseKeymap = [...commands.defaultKeymap, ...CUSTOM_KEYMAP];
1617
1956
  return [
1618
1957
  CodeMirror.EditorView.lineWrapping,
1619
1958
  CodeMirror.keymap.of(extraKeys ? [...extraKeys, ...baseKeymap] : baseKeymap),
1620
- ...codemirrorLangSql.installExtensions({ schema, defaultDatabase, defaultSchema, variables, dialect }),
1959
+ ...codemirrorLangSql.installExtensions({
1960
+ schema,
1961
+ defaultDatabase,
1962
+ defaultSchema,
1963
+ variableCompletion: completeVariables(variables),
1964
+ dialect
1965
+ }),
1621
1966
  searchExtension(),
1622
1967
  highlightingExtension(queryParser),
1968
+ tooltipLayer,
1623
1969
  themeExtension,
1624
1970
  onBlurEditor ? CodeMirror.EditorView.domEventHandlers({ blur: (_, view) => onBlurEditor(view) }) : [],
1625
1971
  onFocusEditor ? CodeMirror.EditorView.domEventHandlers({ focus: (_, view) => onFocusEditor(view) }) : []
@@ -1634,11 +1980,12 @@ var SqlEditor = ({
1634
1980
  dialect,
1635
1981
  onBlurEditor,
1636
1982
  onFocusEditor,
1637
- themeExtension
1983
+ themeExtension,
1984
+ tooltipLayer
1638
1985
  ]);
1639
1986
  const defaultSetup = react.useMemo(() => {
1640
- return { ...BASIS_SETUP2, lineNumbers };
1641
- }, [lineNumbers]);
1987
+ return { ...buildBasicSetup(readOnly), ...OWN_KEYMAPS, lineNumbers };
1988
+ }, [readOnly, lineNumbers]);
1642
1989
  react.useEffect(() => {
1643
1990
  if (editorRef.current?.view) {
1644
1991
  updateHighlighting(editorRef.current.view, highlightLines);
@@ -1704,25 +2051,25 @@ var LINE_HEIGHT_PX = 20;
1704
2051
  var PANE_HEADER_HEIGHT_PX = 58;
1705
2052
  var AcceptButton = ({ side, onAccept }) => {
1706
2053
  const label = `Accept ${side === "left" ? "production" : "branch"} version`;
1707
- const Chevron = side === "left" ? icons_exports.ChevronsRight : icons_exports.ChevronsLeft;
1708
- return /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onAccept, variant: "outline", size: "icon-sm", title: label, "aria-label": label, children: /* @__PURE__ */ jsxRuntime.jsx(Chevron, { className: "tw-size-5" }) });
2054
+ const Chevron = side === "left" ? lucideReact.ChevronsRight : lucideReact.ChevronsLeft;
2055
+ return /* @__PURE__ */ jsxRuntime.jsx(Button, { onClick: onAccept, variant: "outline", size: "icon-sm", title: label, "aria-label": label, children: /* @__PURE__ */ jsxRuntime.jsx(Chevron, { className: "tw:size-5" }) });
1709
2056
  };
1710
2057
  var AcceptControls = ({ conflicts, side, onAccept, onDismiss, contentRef }) => /* @__PURE__ */ jsxRuntime.jsx(
1711
2058
  "div",
1712
2059
  {
1713
2060
  className: cn(
1714
- "tw-z-10 tw-flex tw-shrink-0 tw-flex-col tw-items-center",
1715
- conflicts.length > 0 ? "tw-w-7" : "tw-w-0"
2061
+ "tw:z-10 tw:flex tw:shrink-0 tw:flex-col tw:items-center",
2062
+ conflicts.length > 0 ? "tw:w-7" : "tw:w-0"
1716
2063
  ),
1717
2064
  children: conflicts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1718
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-shrink-0", style: { height: `${PANE_HEADER_HEIGHT_PX}px` } }),
1719
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-relative tw-w-full tw-flex-1 tw-overflow-y-clip tw-overflow-x-visible", children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: contentRef, className: "tw-relative tw-size-full", children: conflicts.map((conflict) => {
2065
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw:shrink-0", style: { height: `${PANE_HEADER_HEIGHT_PX}px` } }),
2066
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw:relative tw:w-full tw:flex-1 tw:overflow-y-clip tw:overflow-x-visible", children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: contentRef, className: "tw:relative tw:size-full", children: conflicts.map((conflict) => {
1720
2067
  const topLine = side === "left" ? conflict.oldStartLine : conflict.newStartLine;
1721
2068
  const topOffset = (topLine - 1) * LINE_HEIGHT_PX - 2;
1722
2069
  return /* @__PURE__ */ jsxRuntime.jsxs(
1723
2070
  "div",
1724
2071
  {
1725
- className: "tw-absolute tw-inset-x-0 tw-flex tw-flex-col tw-items-center tw-gap-0.5",
2072
+ className: "tw:absolute tw:inset-x-0 tw:flex tw:flex-col tw:items-center tw:gap-0.5",
1726
2073
  style: { top: `${topOffset}px` },
1727
2074
  children: [
1728
2075
  /* @__PURE__ */ jsxRuntime.jsx(AcceptButton, { side, onAccept: () => onAccept(conflict) }),
@@ -1734,7 +2081,7 @@ var AcceptControls = ({ conflicts, side, onAccept, onDismiss, contentRef }) => /
1734
2081
  size: "icon-sm",
1735
2082
  title: "Dismiss",
1736
2083
  "aria-label": `Dismiss ${side === "left" ? "production" : "branch"} change`,
1737
- children: /* @__PURE__ */ jsxRuntime.jsx(icons_exports.X, { className: "tw-size-4" })
2084
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "tw:size-4" })
1738
2085
  }
1739
2086
  )
1740
2087
  ]
@@ -1831,13 +2178,15 @@ var MergePane = ({
1831
2178
  deleted = false
1832
2179
  }) => {
1833
2180
  const editorRef = react.useRef(null);
2181
+ const handleChange = useStableCallback((next) => onChange?.(next));
1834
2182
  const themeExtension = useThemedExtension(
2183
+ `merge-pane:${deleted}`,
1835
2184
  () => view.EditorView.theme({
1836
2185
  "&.cm-editor": {
1837
2186
  height: "100%",
1838
2187
  backgroundColor: deleted ? colors__default.default.error[100] : resolveToken("background", "249 250 251"),
1839
2188
  // Pair the token-driven surface with a token-driven text color so line
1840
- // content stays readable when the pane's `--color-background` goes dark.
2189
+ // content stays readable when the pane's `--background` goes dark.
1841
2190
  // The deleted pane keeps default dark text on its fixed light-red wash.
1842
2191
  ...deleted ? {} : { color: resolveToken("foreground", "30 41 59") },
1843
2192
  outline: "none"
@@ -1848,10 +2197,13 @@ var MergePane = ({
1848
2197
  },
1849
2198
  "*": { lineHeight: `${LINE_HEIGHT_PX}px` },
1850
2199
  ".cm-lineNumbers .cm-gutterElement": { padding: "0 0 0 25px" }
1851
- }),
1852
- [deleted]
2200
+ })
1853
2201
  );
1854
2202
  const diffHighlightExtension = react.useMemo(() => createDiffHighlightExtension(), []);
2203
+ const basicSetup = react.useMemo(
2204
+ () => ({ ...buildBasicSetup(readOnly), lineNumbers: true }),
2205
+ [readOnly]
2206
+ );
1855
2207
  const extensions = react.useMemo(
1856
2208
  () => [
1857
2209
  diffHighlightExtension,
@@ -1901,33 +2253,33 @@ var MergePane = ({
1901
2253
  "div",
1902
2254
  {
1903
2255
  className: cn(
1904
- "tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-overflow-hidden",
2256
+ "tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:overflow-hidden",
1905
2257
  className,
1906
- deleted && "tw-border-error-300"
2258
+ deleted && "tw:border-error-300"
1907
2259
  ),
1908
2260
  children: [
1909
2261
  header && /* @__PURE__ */ jsxRuntime.jsx(
1910
2262
  "div",
1911
2263
  {
1912
2264
  className: cn(
1913
- "tw-px-4 tw-py-3",
1914
- deleted ? "tw-border-b tw-border-error-200 tw-bg-error-100" : "tw-bg-background",
2265
+ "tw:px-4 tw:py-3",
2266
+ deleted ? "tw:border-b tw:border-error-200 tw:bg-error-100" : "tw:bg-background",
1915
2267
  headerClassName
1916
2268
  ),
1917
2269
  children: header
1918
2270
  }
1919
2271
  ),
1920
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-flex tw-h-0 tw-flex-1 tw-flex-col [&_>div]:tw-h-full", children: /* @__PURE__ */ jsxRuntime.jsx(
2272
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw:flex tw:h-0 tw:flex-1 tw:flex-col tw:[&_>div]:h-full", children: /* @__PURE__ */ jsxRuntime.jsx(
1921
2273
  CodeMirror__default.default,
1922
2274
  {
1923
2275
  ref: editorRef,
1924
2276
  height: "100%",
1925
2277
  value,
1926
- onChange,
2278
+ onChange: handleChange,
1927
2279
  extensions,
1928
2280
  readOnly,
1929
2281
  onCreateEditor: handleCreateEditor,
1930
- basicSetup: { lineNumbers: true, drawSelection: false }
2282
+ basicSetup
1931
2283
  }
1932
2284
  ) })
1933
2285
  ]
@@ -2027,7 +2379,7 @@ var MergeEditor = ({
2027
2379
  "div",
2028
2380
  {
2029
2381
  className: cn(
2030
- "tw-flex tw-h-full tw-min-h-0 tw-overflow-hidden tw-bg-background tw-gap-3",
2382
+ "tw:flex tw:h-full tw:min-h-0 tw:overflow-hidden tw:bg-background tw:gap-3",
2031
2383
  className
2032
2384
  ),
2033
2385
  children: [
@@ -2039,7 +2391,7 @@ var MergeEditor = ({
2039
2391
  lineClassification: leftClassification,
2040
2392
  readOnly: true,
2041
2393
  header: leftHeader,
2042
- className: "tw-rounded-r-lg tw-border tw-border-border",
2394
+ className: "tw:rounded-r-lg tw:border tw:border-border",
2043
2395
  onScrollDOMReady: registerScroller(0),
2044
2396
  deleted: leftDeleted
2045
2397
  }
@@ -2063,7 +2415,7 @@ var MergeEditor = ({
2063
2415
  onChange: handleMergeChange,
2064
2416
  header: middleHeader,
2065
2417
  headerClassName: middleHeaderClassName,
2066
- className: cn("tw-border tw-border-border tw-rounded-lg", middleClassName),
2418
+ className: cn("tw:border tw:border-border tw:rounded-lg", middleClassName),
2067
2419
  onScrollDOMReady: registerScroller(1)
2068
2420
  }
2069
2421
  ),
@@ -2085,7 +2437,7 @@ var MergeEditor = ({
2085
2437
  lineClassification: rightClassification,
2086
2438
  readOnly: true,
2087
2439
  header: rightHeader,
2088
- className: "tw-rounded-l-lg tw-border tw-border-border",
2440
+ className: "tw:rounded-l-lg tw:border tw:border-border",
2089
2441
  onScrollDOMReady: registerScroller(2),
2090
2442
  deleted: rightDeleted
2091
2443
  }
@@ -2096,7 +2448,9 @@ var MergeEditor = ({
2096
2448
  };
2097
2449
 
2098
2450
  exports.CodeEditor = CodeEditor;
2451
+ exports.LANGUAGE_MODES = LANGUAGE_MODES;
2099
2452
  exports.MergeEditor = MergeEditor;
2100
2453
  exports.SqlEditor = SqlEditor;
2454
+ exports.isLanguageMode = isLanguageMode;
2101
2455
  //# sourceMappingURL=editors.cjs.map
2102
2456
  //# sourceMappingURL=editors.cjs.map