@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.js CHANGED
@@ -1,9 +1,9 @@
1
- import { createContext, forwardRef, useMemo, useRef, useEffect, useCallback, useSyncExternalStore, useState, use, Children, Fragment as Fragment$1 } from 'react';
2
- import { completeAnyWord, autocompletion } from '@codemirror/autocomplete';
1
+ import { createContext, useRef, useEffect, useLayoutEffect, useMemo, useCallback, useSyncExternalStore, useState, use, Children, Fragment as Fragment$1 } from 'react';
2
+ import { completeFromList, completeAnyWord, autocompletion } from '@codemirror/autocomplete';
3
3
  import { jsonParseLinter, json } from '@codemirror/lang-json';
4
4
  import { linter } from '@codemirror/lint';
5
5
  import { unifiedMergeView } from '@codemirror/merge';
6
- import { Decoration, gutter, EditorView, ViewPlugin, GutterMarker, keymap, placeholder, gutterLineClass } from '@codemirror/view';
6
+ import { EditorView, Decoration, ViewPlugin, gutter, GutterMarker, keymap, placeholder, tooltips, gutterLineClass } from '@codemirror/view';
7
7
  import CodeMirror, { EditorState, EditorView as EditorView$1, keymap as keymap$1 } from '@uiw/react-codemirror';
8
8
  import { clsx } from 'clsx';
9
9
  import { extendTailwindMerge } from 'tailwind-merge';
@@ -12,37 +12,23 @@ import { cva } from 'class-variance-authority';
12
12
  import { keboolaLegacySidebar, keboolaLegacyTopnav } from '@keboola/brand-registry';
13
13
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
14
14
  import { Root, Slottable } from '@radix-ui/react-slot';
15
- import * as lucide_react_star from 'lucide-react';
15
+ import { X, ChevronsRight, ChevronsLeft, Loader2, Copy } from 'lucide-react';
16
16
  import { javascript } from '@codemirror/lang-javascript';
17
17
  import { python } from '@codemirror/lang-python';
18
- import { sql, PLSQL } from '@codemirror/lang-sql';
18
+ import { sql, PLSQL, MSSQL, PostgreSQL, MySQL } from '@codemirror/lang-sql';
19
19
  import { StreamLanguage } from '@codemirror/language';
20
20
  import { r } from '@codemirror/legacy-modes/mode/r';
21
21
  import { shell } from '@codemirror/legacy-modes/mode/shell';
22
+ import { toml } from '@codemirror/legacy-modes/mode/toml';
22
23
  import { githubLightInit } from '@uiw/codemirror-theme-github';
23
- import { sfsql } from '@keboola/codemirror-lang-sfsql';
24
+ import { modeSpec, sfsql } from '@keboola/codemirror-lang-sfsql';
24
25
  import colors from '@keboola/tailwind-config/colors';
26
+ import { simpleMode } from '@codemirror/legacy-modes/mode/simple-mode';
27
+ import { StateEffect, StateField, RangeSet, Compartment, RangeSetBuilder } from '@codemirror/state';
25
28
  import { defaultKeymap } from '@codemirror/commands';
26
29
  import { installExtensions } from '@keboola/codemirror-lang-sql';
27
- import { StateEffect, StateField, RangeSet, RangeSetBuilder } from '@codemirror/state';
28
30
 
29
- var __defProp = Object.defineProperty;
30
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
31
- var __getOwnPropNames = Object.getOwnPropertyNames;
32
- var __hasOwnProp = Object.prototype.hasOwnProperty;
33
- var __export = (target, all) => {
34
- for (var name in all)
35
- __defProp(target, name, { get: all[name], enumerable: true });
36
- };
37
- var __copyProps = (to, from, except, desc) => {
38
- if (from && typeof from === "object" || typeof from === "function") {
39
- for (let key of __getOwnPropNames(from))
40
- if (!__hasOwnProp.call(to, key) && key !== except)
41
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
42
- }
43
- return to;
44
- };
45
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget);
31
+ // src/components/CodeEditor/CodeEditor.tsx
46
32
 
47
33
  // src/constants/keyCodes.ts
48
34
  var keyCodes = {
@@ -50,8 +36,15 @@ var keyCodes = {
50
36
  ESCAPE: "Escape",
51
37
  SPACE: " "
52
38
  };
39
+ var useStableCallback = (callback) => {
40
+ const latestRef = useRef(callback);
41
+ useLayoutEffect(() => {
42
+ latestRef.current = callback;
43
+ }, [callback]);
44
+ return useCallback((...args) => latestRef.current(...args), []);
45
+ };
53
46
  var twMerge = extendTailwindMerge({
54
- prefix: "tw-"
47
+ prefix: "tw"
55
48
  });
56
49
  var cn = (...classes) => twMerge(clsx(...classes));
57
50
 
@@ -95,39 +88,39 @@ var useArgoDesign = () => use(ArgoDesignContext);
95
88
  var tooltipVariants = cva(
96
89
  [
97
90
  "tailwindcss-preflight",
98
- "tw-inline-block",
99
- "tw-break-anywhere",
100
- "tw-max-h-96",
101
- "tw-overflow-y-auto",
102
- "tw-z-[1060]",
91
+ "tw:inline-block",
92
+ "tw:break-anywhere",
93
+ "tw:max-h-96",
94
+ "tw:overflow-y-auto",
95
+ "tw:z-[1060]",
103
96
  // legacy (dark) chrome — default
104
- "tw-rounded",
105
- "tw-bg-neutral-800",
106
- "tw-text-white",
97
+ "tw:rounded",
98
+ "tw:bg-neutral-800",
99
+ "tw:text-white",
107
100
  // argo chrome overrides — semantic floating-panel tokens
108
- "data-[argo=true]:tw-rounded-2xl",
109
- "data-[argo=true]:tw-border",
110
- "data-[argo=true]:tw-border-solid",
111
- "data-[argo=true]:tw-border-border",
112
- "data-[argo=true]:tw-bg-popover",
113
- "data-[argo=true]:tw-text-popover-foreground",
114
- "data-[argo=true]:tw-shadow-md",
101
+ "tw:data-[argo=true]:rounded-2xl",
102
+ "tw:data-[argo=true]:border",
103
+ "tw:data-[argo=true]:border-solid",
104
+ "tw:data-[argo=true]:border-border",
105
+ "tw:data-[argo=true]:bg-popover",
106
+ "tw:data-[argo=true]:text-popover-foreground",
107
+ "tw:data-[argo=true]:shadow-md",
115
108
  // argo open animation
116
- "data-[argo=true]:data-[state=delayed-open]:tw-animate-in",
117
- "data-[argo=true]:data-[state=instant-open]:tw-animate-in",
118
- "data-[argo=true]:data-[state=delayed-open]:tw-fade-in-0",
119
- "data-[argo=true]:data-[state=instant-open]:tw-fade-in-0",
120
- "data-[argo=true]:data-[state=delayed-open]:tw-zoom-in-95",
121
- "data-[argo=true]:data-[state=instant-open]:tw-zoom-in-95",
109
+ "tw:data-[argo=true]:data-[state=delayed-open]:animate-in",
110
+ "tw:data-[argo=true]:data-[state=instant-open]:animate-in",
111
+ "tw:data-[argo=true]:data-[state=delayed-open]:fade-in-0",
112
+ "tw:data-[argo=true]:data-[state=instant-open]:fade-in-0",
113
+ "tw:data-[argo=true]:data-[state=delayed-open]:zoom-in-95",
114
+ "tw:data-[argo=true]:data-[state=instant-open]:zoom-in-95",
122
115
  // argo closed animation
123
- "data-[argo=true]:data-[state=closed]:tw-animate-out",
124
- "data-[argo=true]:data-[state=closed]:tw-fade-out-0",
125
- "data-[argo=true]:data-[state=closed]:tw-zoom-out-95",
116
+ "tw:data-[argo=true]:data-[state=closed]:animate-out",
117
+ "tw:data-[argo=true]:data-[state=closed]:fade-out-0",
118
+ "tw:data-[argo=true]:data-[state=closed]:zoom-out-95",
126
119
  // argo position animation
127
- "data-[argo=true]:data-[side=bottom]:tw-slide-in-from-top-2",
128
- "data-[argo=true]:data-[side=left]:tw-slide-in-from-right-2",
129
- "data-[argo=true]:data-[side=right]:tw-slide-in-from-left-2",
130
- "data-[argo=true]:data-[side=top]:tw-slide-in-from-bottom-2"
120
+ "tw:data-[argo=true]:data-[side=bottom]:slide-in-from-top-2",
121
+ "tw:data-[argo=true]:data-[side=left]:slide-in-from-right-2",
122
+ "tw:data-[argo=true]:data-[side=right]:slide-in-from-left-2",
123
+ "tw:data-[argo=true]:data-[side=top]:slide-in-from-bottom-2"
131
124
  ],
132
125
  {
133
126
  defaultVariants: {
@@ -136,22 +129,26 @@ var tooltipVariants = cva(
136
129
  variants: {
137
130
  variant: {
138
131
  action: [
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
- "tw-uppercase",
146
- "tw-tracking-wider"
132
+ "tw:max-w-fit",
133
+ "tw:px-3",
134
+ "tw:py-2",
135
+ "tw:text-center",
136
+ "tw:text-xs",
137
+ "tw:font-medium",
138
+ // Legacy chrome uppercases the action tooltip; the Keboola V2 brand
139
+ // (`data-brand="keboola"`) renders it in standard case instead.
140
+ "tw:uppercase",
141
+ "tw:tracking-wider",
142
+ "tw:[[data-brand=keboola]_&]:normal-case",
143
+ "tw:[[data-brand=keboola]_&]:tracking-normal"
147
144
  ],
148
145
  explanatory: [
149
- "tw-max-w-80",
150
- "tw-px-4",
151
- "tw-py-3",
152
- "tw-text-left",
153
- "tw-text-sm",
154
- "tw-font-normal"
146
+ "tw:max-w-80",
147
+ "tw:px-4",
148
+ "tw:py-3",
149
+ "tw:text-left",
150
+ "tw:text-sm",
151
+ "tw:font-normal"
155
152
  ]
156
153
  }
157
154
  }
@@ -225,8 +222,8 @@ var TooltipTrigger = ({
225
222
  // (merged in via Slot) activates Tailwind's preflight inside the
226
223
  // span, which sets `svg { display: block }` — without an inline-flex
227
224
  // container that would stack any bare Lucide icon onto its own
228
- // line. `tw-inline-flex tw-items-center` keeps icon + text aligned.
229
- /* @__PURE__ */ jsx("span", { className: "tw-inline-flex tw-items-center", children })
225
+ // line. `tw:inline-flex tw:items-center` keeps icon + text aligned.
226
+ /* @__PURE__ */ jsx("span", { className: "tw:inline-flex tw:items-center", children })
230
227
  )
231
228
  }
232
229
  );
@@ -293,14 +290,29 @@ Tooltip.Trigger = TooltipTrigger;
293
290
 
294
291
  // src/utils/escapeStringRegexp.ts
295
292
  var escapeStringRegexp = (string) => string.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
296
- var helpVariants = cva(["tw-m-0", "tw-text-xs"], {
293
+
294
+ // src/utils/isMac.ts
295
+ var getIsMac = () => {
296
+ if (typeof navigator !== "undefined" && "userAgentData" in navigator) {
297
+ const platform = navigator.userAgentData.platform;
298
+ if (typeof platform === "string") {
299
+ return platform.toLowerCase() === "macos";
300
+ }
301
+ }
302
+ if (typeof navigator !== "undefined" && typeof navigator.platform === "string") {
303
+ return navigator.platform.toUpperCase().indexOf("MAC") >= 0;
304
+ }
305
+ return false;
306
+ };
307
+ var isMac = getIsMac();
308
+ var helpVariants = cva(["tw:m-0", "tw:text-xs"], {
297
309
  defaultVariants: {
298
310
  state: "default"
299
311
  },
300
312
  variants: {
301
313
  state: {
302
- default: ["tw-text-muted-foreground"],
303
- warning: ["tw-text-warning"]
314
+ default: ["tw:text-muted-foreground"],
315
+ warning: ["tw:text-warning"]
304
316
  }
305
317
  }
306
318
  });
@@ -308,146 +320,49 @@ var HelpBlock = ({ children, className, state = "default", ...rest }) => {
308
320
  if (!children) return null;
309
321
  return /* @__PURE__ */ jsx("p", { ...rest, className: helpVariants({ state, className }), children });
310
322
  };
311
-
312
- // src/icons/index.ts
313
- var icons_exports = {};
314
- __export(icons_exports, {
315
- Google: () => Google,
316
- Keboola: () => Keboola,
317
- Microsoft: () => Microsoft
318
- });
319
- __reExport(icons_exports, lucide_react_star);
320
- var Google = forwardRef(
321
- ({ size = 24, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(
322
- "svg",
323
- {
324
- ref,
325
- xmlns: "http://www.w3.org/2000/svg",
326
- width: size,
327
- height: size,
328
- viewBox: "12 10 20 20",
329
- fill: "none",
330
- className: cn("lucide", className),
331
- ...rest,
332
- children: [
333
- /* @__PURE__ */ jsx(
334
- "path",
335
- {
336
- 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",
337
- fill: "#4285F4"
338
- }
339
- ),
340
- /* @__PURE__ */ jsx(
341
- "path",
342
- {
343
- 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",
344
- fill: "#34A853"
345
- }
346
- ),
347
- /* @__PURE__ */ jsx(
348
- "path",
349
- {
350
- 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",
351
- fill: "#FBBC04"
352
- }
353
- ),
354
- /* @__PURE__ */ jsx(
355
- "path",
356
- {
357
- 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",
358
- fill: "#EA4335"
359
- }
360
- ),
361
- children
362
- ]
363
- }
364
- )
365
- );
366
- Google.displayName = "Google";
367
- var Keboola = forwardRef(
368
- ({ size = 24, color = "currentColor", className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(
369
- "svg",
370
- {
371
- ref,
372
- xmlns: "http://www.w3.org/2000/svg",
373
- width: size,
374
- height: size,
375
- viewBox: "0 0 300 512",
376
- overflow: "visible",
377
- fill: color,
378
- className: cn("lucide", className),
379
- ...rest,
380
- children: [
381
- /* @__PURE__ */ 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" }),
382
- children
383
- ]
384
- }
385
- )
386
- );
387
- Keboola.displayName = "Keboola";
388
- var Microsoft = forwardRef(
389
- ({ size = 24, className, children, ...rest }, ref) => /* @__PURE__ */ jsxs(
390
- "svg",
391
- {
392
- ref,
393
- xmlns: "http://www.w3.org/2000/svg",
394
- width: size,
395
- height: size,
396
- viewBox: "0 0 21 21",
397
- fill: "none",
398
- className: cn("lucide", className),
399
- ...rest,
400
- children: [
401
- /* @__PURE__ */ jsx("rect", { x: "0", y: "0", width: "10", height: "10", fill: "#F25022" }),
402
- /* @__PURE__ */ jsx("rect", { x: "11", y: "0", width: "10", height: "10", fill: "#7FBA00" }),
403
- /* @__PURE__ */ jsx("rect", { x: "0", y: "11", width: "10", height: "10", fill: "#00A4EF" }),
404
- /* @__PURE__ */ jsx("rect", { x: "11", y: "11", width: "10", height: "10", fill: "#FFB900" }),
405
- children
406
- ]
407
- }
408
- )
409
- );
410
- Microsoft.displayName = "Microsoft";
411
323
  var variants = cva(
412
324
  [
413
325
  "tailwindcss-preflight",
414
- "tw-group/button",
415
- "tw-border-box",
326
+ "tw:group/button",
327
+ "tw:border-box",
416
328
  // layout
417
- "tw-relative",
418
- "tw-flex",
419
- "tw-items-center",
420
- "tw-justify-center",
421
- "tw-gap-2",
329
+ "tw:relative",
330
+ "tw:flex",
331
+ "tw:items-center",
332
+ "tw:justify-center",
333
+ "tw:gap-2",
422
334
  // text — chrome weight/tracking are brand-overridable tokens
423
- // (`--font-weight-medium` / `--letter-spacing-chrome`); casing stays `tw-uppercase`.
424
- "tw-text-xs",
425
- "tw-leading-5",
426
- "tw-font-medium",
427
- "tw-tracking-chrome",
428
- "tw-uppercase",
335
+ // (`--font-weight-medium` / `--letter-spacing-chrome`). Casing: standard case is
336
+ // the default; only legacy brands (`keboola-legacy-*`) uppercase the chrome, so
337
+ // modern brands (incl. Keboola V2) read naturally. Mirrors the V2 standard-case
338
+ // treatment shipped for Tooltip/Badge (PR 7629).
339
+ "tw:text-xs",
340
+ "tw:leading-5",
341
+ "tw:font-medium",
342
+ "tw:[[data-brand^=keboola-legacy]_&]:tracking-chrome",
343
+ "tw:[[data-brand^=keboola-legacy]_&]:uppercase",
429
344
  // border — legacy (non-argo) chrome uses a fixed radius, not the brand token.
430
- "tw-rounded",
431
- "tw-border",
432
- "tw-border-transparent",
345
+ "tw:rounded",
346
+ "tw:border",
347
+ "tw:border-transparent",
433
348
  // styling
434
- "tw-shadow-none",
435
- "[a]:tw-cursor-pointer",
349
+ "tw:shadow-none",
350
+ "tw:[a]:cursor-pointer",
436
351
  // explicitly set for anchor
437
- "focus-visible:tw-outline",
438
- "focus-visible:tw-outline-1",
439
- "focus-visible:-tw-outline-offset-1",
440
- "focus-visible:tw-outline-ring",
441
- "focus-visible:tw-ring-4",
442
- "focus-visible:tw-ring-ring/30",
352
+ "tw:focus-visible:outline",
353
+ "tw:focus-visible:outline-1",
354
+ "tw:focus-visible:-outline-offset-1",
355
+ "tw:focus-visible:outline-ring",
356
+ "tw:focus-visible:ring-4",
357
+ "tw:focus-visible:ring-ring/30",
443
358
  // disabled
444
- "disabled:tw-opacity-40",
445
- "disabled:tw-cursor-not-allowed",
359
+ "tw:disabled:opacity-40",
360
+ "tw:disabled:cursor-not-allowed",
446
361
  // anchor support
447
- "!tw-no-underline",
448
- "aria-disabled:tw-opacity-40",
449
- "aria-disabled:tw-cursor-not-allowed",
450
- "[&_svg]:tw-shrink-0"
362
+ "tw:!no-underline",
363
+ "tw:aria-disabled:opacity-40",
364
+ "tw:aria-disabled:cursor-not-allowed",
365
+ "tw:[&_svg]:shrink-0"
451
366
  ],
452
367
  {
453
368
  defaultVariants: {
@@ -457,113 +372,113 @@ var variants = cva(
457
372
  },
458
373
  variants: {
459
374
  block: {
460
- true: ["tw-w-full"]
375
+ true: ["tw:w-full"]
461
376
  },
462
377
  variant: {
463
378
  primary: [
464
- "tw-text-white",
465
- "tw-bg-primary-500",
466
- "focus:tw-text-white",
467
- "hover:tw-text-white",
468
- "hover:not-disabled:tw-bg-primary-600",
469
- "active:not-disabled:tw-bg-primary-800",
379
+ "tw:text-white",
380
+ "tw:bg-primary-500",
381
+ "tw:focus:text-white",
382
+ "tw:hover:text-white",
383
+ "tw:hover:not-disabled:bg-primary-600",
384
+ "tw:active:not-disabled:bg-primary-800",
470
385
  // anchor disabled override
471
- "aria-disabled:!tw-bg-primary-500"
386
+ "tw:aria-disabled:!bg-primary-500"
472
387
  ],
473
388
  secondary: [
474
- "tw-text-white",
475
- "tw-bg-secondary-500",
476
- "focus:tw-text-white",
477
- "hover:tw-text-white",
478
- "hover:not-disabled:tw-bg-secondary-700",
479
- "active:not-disabled:tw-bg-secondary-800",
389
+ "tw:text-white",
390
+ "tw:bg-secondary-500",
391
+ "tw:focus:text-white",
392
+ "tw:hover:text-white",
393
+ "tw:hover:not-disabled:bg-secondary-700",
394
+ "tw:active:not-disabled:bg-secondary-800",
480
395
  // anchor disabled override
481
- "aria-disabled:!tw-bg-secondary-500"
396
+ "tw:aria-disabled:!bg-secondary-500"
482
397
  ],
483
398
  danger: [
484
- "tw-text-white",
485
- "tw-bg-error-500",
486
- "focus:tw-text-white",
487
- "hover:tw-text-white",
488
- "hover:not-disabled:tw-bg-error-600",
489
- "active:not-disabled:tw-bg-error-700",
399
+ "tw:text-white",
400
+ "tw:bg-error-500",
401
+ "tw:focus:text-white",
402
+ "tw:hover:text-white",
403
+ "tw:hover:not-disabled:bg-error-600",
404
+ "tw:active:not-disabled:bg-error-700",
490
405
  // anchor disabled override
491
- "aria-disabled:!tw-bg-error-500"
406
+ "tw:aria-disabled:!bg-error-500"
492
407
  ],
493
408
  invisible: [
494
- "tw-text-neutral-800",
495
- "tw-bg-transparent",
496
- "focus:tw-text-neutral-800",
497
- "hover:not-disabled:tw-bg-neutral-100",
498
- "hover:tw-text-neutral-800",
499
- "active:not-disabled:tw-bg-neutral-150",
409
+ "tw:text-neutral-800",
410
+ "tw:bg-transparent",
411
+ "tw:focus:text-neutral-800",
412
+ "tw:hover:not-disabled:bg-neutral-100",
413
+ "tw:hover:text-neutral-800",
414
+ "tw:active:not-disabled:bg-neutral-150",
500
415
  // contrasting icon on hover/active
501
- "[&_svg]:tw-text-neutral-400",
502
- "[&_svg]:hover:not-disabled:tw-text-secondary-600",
503
- "[&_svg]:active:not-disabled:tw-text-secondary-600",
416
+ "tw:[&_svg]:text-neutral-400",
417
+ "tw:hover:not-disabled:[&_svg]:text-secondary-600",
418
+ "tw:active:not-disabled:[&_svg]:text-secondary-600",
504
419
  // anchor disabled override
505
- "aria-disabled:!tw-bg-transparent"
420
+ "tw:aria-disabled:!bg-transparent"
506
421
  ],
507
422
  outline: [
508
- "tw-text-neutral-800",
509
- "tw-bg-white",
423
+ "tw:text-neutral-800",
424
+ "tw:bg-white",
510
425
  // border
511
- "!tw-border-neutral-200",
512
- "hover:tw-text-neutral-800",
513
- "focus:tw-text-neutral-800",
514
- "hover:not-disabled:!tw-border-neutral-300",
515
- "hover:not-disabled:tw-bg-neutral-100",
516
- "active:not-disabled:tw-bg-neutral-200",
426
+ "tw:!border-neutral-200",
427
+ "tw:hover:text-neutral-800",
428
+ "tw:focus:text-neutral-800",
429
+ "tw:hover:not-disabled:!border-neutral-300",
430
+ "tw:hover:not-disabled:bg-neutral-100",
431
+ "tw:active:not-disabled:bg-neutral-200",
517
432
  // contrasting icon hover, same as invisible
518
- "[&_svg]:tw-text-neutral-400",
519
- "[&_svg]:not-disabled:hover:tw-text-secondary-600",
520
- "[&_svg]:active:not-disabled:tw-text-secondary-600",
433
+ "tw:[&_svg]:text-neutral-400",
434
+ "tw:not-disabled:hover:[&_svg]:text-secondary-600",
435
+ "tw:active:not-disabled:[&_svg]:text-secondary-600",
521
436
  // anchor disabled override
522
- "aria-disabled:!tw-bg-white",
523
- "aria-disabled:!tw-border-neutral-200"
437
+ "tw:aria-disabled:!bg-white",
438
+ "tw:aria-disabled:!border-neutral-200"
524
439
  ],
525
440
  inline: [
526
- "tw-text-neutral-800",
527
- "tw-bg-transparent",
528
- "tw-rounded-full",
529
- "[&_svg]:tw-text-neutral-400",
530
- "[&_svg]:not-disabled:hover:tw-text-secondary-600",
531
- "[&_svg]:not-disabled:focus:tw-text-secondary-600"
441
+ "tw:text-neutral-800",
442
+ "tw:bg-transparent",
443
+ "tw:rounded-full",
444
+ "tw:[&_svg]:text-neutral-400",
445
+ "tw:not-disabled:hover:[&_svg]:text-secondary-600",
446
+ "tw:not-disabled:focus:[&_svg]:text-secondary-600"
532
447
  ]
533
448
  },
534
449
  size: {
535
450
  medium: [
536
- "tw-max-h-10",
537
- "tw-min-h-10",
538
- "tw-px-4",
539
- "tw-py-2.5",
540
- '[&_svg:not([class*="tw-size-"])]:tw-size-4'
451
+ "tw:max-h-10",
452
+ "tw:min-h-10",
453
+ "tw:px-4",
454
+ "tw:py-2.5",
455
+ 'tw:[&_svg:not([class*="tw:size-"])]:size-4'
541
456
  ],
542
457
  small: [
543
- "tw-max-h-8",
544
- "tw-min-h-8",
545
- "tw-px-4",
546
- "tw-py-1.5",
547
- '[&_svg:not([class*="tw-size-"])]:tw-size-4'
458
+ "tw:max-h-8",
459
+ "tw:min-h-8",
460
+ "tw:px-4",
461
+ "tw:py-1.5",
462
+ 'tw:[&_svg:not([class*="tw:size-"])]:size-4'
548
463
  ],
549
464
  large: [
550
- "tw-max-h-12",
551
- "tw-min-h-12",
552
- "tw-px-4",
553
- "tw-py-3.5",
554
- '[&_svg:not([class*="tw-size-"])]:tw-size-4'
465
+ "tw:max-h-12",
466
+ "tw:min-h-12",
467
+ "tw:px-4",
468
+ "tw:py-3.5",
469
+ 'tw:[&_svg:not([class*="tw:size-"])]:size-4'
555
470
  ],
556
- "icon-lg": ["tw-size-12", "tw-p-0", '[&_svg:not([class*="tw-size-"])]:tw-size-6'],
557
- icon: ["tw-size-10", "tw-p-0", '[&_svg:not([class*="tw-size-"])]:tw-size-4'],
558
- "icon-sm": ["tw-size-8", "tw-p-0", '[&_svg:not([class*="tw-size-"])]:tw-size-4'],
559
- "icon-xs": ["tw-size-6", "tw-p-0", '[&_svg:not([class*="tw-size-"])]:tw-size-4'],
471
+ "icon-lg": ["tw:size-12", "tw:p-0", 'tw:[&_svg:not([class*="tw:size-"])]:size-6'],
472
+ icon: ["tw:size-10", "tw:p-0", 'tw:[&_svg:not([class*="tw:size-"])]:size-4'],
473
+ "icon-sm": ["tw:size-8", "tw:p-0", 'tw:[&_svg:not([class*="tw:size-"])]:size-4'],
474
+ "icon-xs": ["tw:size-6", "tw:p-0", 'tw:[&_svg:not([class*="tw:size-"])]:size-4'],
560
475
  "icon-2xs": [
561
- "!tw-inline-flex",
562
- "tw-size-5",
563
- "tw-max-h-5",
564
- '[&_svg:not([class*="tw-size-"])]:tw-size-3'
476
+ "tw:!inline-flex",
477
+ "tw:size-5",
478
+ "tw:max-h-5",
479
+ 'tw:[&_svg:not([class*="tw:size-"])]:size-3'
565
480
  ],
566
- "icon-3xs": ["tw-h-fit", "tw-w-fit", '[&_svg:not([class*="tw-size-"])]:tw-size-4']
481
+ "icon-3xs": ["tw:h-fit", "tw:w-fit", 'tw:[&_svg:not([class*="tw:size-"])]:size-4']
567
482
  }
568
483
  }
569
484
  }
@@ -572,37 +487,37 @@ var argoVariants = cva(
572
487
  [
573
488
  "tailwindcss-preflight",
574
489
  // layout
575
- "tw-relative",
576
- "tw-inline-flex",
577
- "tw-items-center",
578
- "tw-justify-center",
579
- "tw-whitespace-nowrap",
580
- "tw-gap-2",
490
+ "tw:relative",
491
+ "tw:inline-flex",
492
+ "tw:items-center",
493
+ "tw:justify-center",
494
+ "tw:whitespace-nowrap",
495
+ "tw:gap-2",
581
496
  // border
582
- "tw-border",
583
- "tw-border-transparent",
584
- "tw-rounded-[var(--radius-lg,0.25rem)]",
497
+ "tw:border",
498
+ "tw:border-transparent",
499
+ "tw:rounded-[var(--radius-lg,0.25rem)]",
585
500
  // text
586
- "tw-font-medium",
587
- "tw-select-none",
501
+ "tw:font-medium",
502
+ "tw:select-none",
588
503
  // focus visible
589
- "!tw-outline-none",
590
- "focus-visible:tw-ring-2",
504
+ "tw:!outline-hidden",
505
+ "tw:focus-visible:ring-2",
591
506
  // disabled
592
- "disabled:tw-cursor-not-allowed",
593
- "disabled:tw-opacity-50",
594
- "active:tw-opacity-60",
595
- "tw-transition-all",
596
- "tw-bg-clip-padding",
507
+ "tw:disabled:cursor-not-allowed",
508
+ "tw:disabled:opacity-50",
509
+ "tw:active:opacity-60",
510
+ "tw:transition-all",
511
+ "tw:bg-clip-padding",
597
512
  // anchor support
598
- "!tw-no-underline",
599
- "aria-disabled:tw-cursor-not-allowed",
600
- "aria-disabled:tw-opacity-50",
513
+ "tw:!no-underline",
514
+ "tw:aria-disabled:cursor-not-allowed",
515
+ "tw:aria-disabled:opacity-50",
601
516
  // icon
602
- "tw-shrink-0",
603
- "[&_svg]:tw-pointer-events-none",
604
- "[&_svg]:tw-shrink-0",
605
- "[&_svg:not([class*='tw-size-'])]:tw-size-4"
517
+ "tw:shrink-0",
518
+ "tw:[&_svg]:pointer-events-none",
519
+ "tw:[&_svg]:shrink-0",
520
+ "tw:[&_svg:not([class*='tw:size-'])]:size-4"
606
521
  ],
607
522
  {
608
523
  defaultVariants: {
@@ -611,77 +526,77 @@ var argoVariants = cva(
611
526
  },
612
527
  variants: {
613
528
  block: {
614
- true: ["tw-w-full"]
529
+ true: ["tw:w-full"]
615
530
  },
616
531
  variant: {
617
532
  primary: [
618
- "tw-bg-primary",
619
- "tw-text-primary-foreground",
620
- "[a]:hover:tw-bg-primary/80",
621
- "hover:not-disabled:tw-bg-primary/90",
622
- "hover:tw-text-primary-foreground",
623
- "focus:tw-text-primary-foreground",
624
- "focus-visible:tw-border-primary",
625
- "focus-visible:tw-ring-ring/50"
533
+ "tw:bg-primary",
534
+ "tw:text-primary-foreground",
535
+ "tw:[a]:hover:bg-primary/80",
536
+ "tw:hover:not-disabled:bg-primary/90",
537
+ "tw:hover:text-primary-foreground",
538
+ "tw:focus:text-primary-foreground",
539
+ "tw:focus-visible:border-primary",
540
+ "tw:focus-visible:ring-ring/50"
626
541
  ],
627
542
  secondary: [
628
- "tw-bg-primary/10",
629
- "tw-text-primary",
630
- "hover:not-disabled:tw-bg-primary/20",
631
- "focus-visible:tw-border-primary",
632
- "focus-visible:tw-ring-ring/50"
543
+ "tw:bg-primary/10",
544
+ "tw:text-primary",
545
+ "tw:hover:not-disabled:bg-primary/20",
546
+ "tw:focus-visible:border-primary",
547
+ "tw:focus-visible:ring-ring/50"
633
548
  ],
634
549
  // should be called "destructive" by Figma
635
550
  danger: [
636
- "tw-bg-destructive",
637
- "tw-text-destructive-foreground",
638
- "hover:tw-text-destructive-foreground",
639
- "focus:tw-text-destructive-foreground",
640
- "focus-visible:tw-border-destructive",
641
- "focus-visible:tw-ring-destructive/20"
551
+ "tw:bg-destructive",
552
+ "tw:text-destructive-foreground",
553
+ "tw:hover:text-destructive-foreground",
554
+ "tw:focus:text-destructive-foreground",
555
+ "tw:focus-visible:border-destructive",
556
+ "tw:focus-visible:ring-destructive/20"
642
557
  ],
643
558
  outline: [
644
- "!tw-border-input",
645
- "tw-bg-background",
559
+ "tw:!border-input",
560
+ "tw:bg-background",
646
561
  // Semantic base text color so the label/icon flips in dark mode
647
562
  // (matches `invisible`); previously unset → inherited a fixed dark color.
648
- "tw-text-foreground",
563
+ "tw:text-foreground",
649
564
  // Hover follows the brand primary (translucent tint), matching the
650
565
  // `secondary` variant — not the fixed `accent` blue.
651
- "hover:not-disabled:tw-bg-primary/10",
652
- "hover:not-disabled:tw-text-primary",
653
- "hover:active:tw-bg-background",
654
- "focus-visible:!tw-border-primary",
655
- "focus-visible:tw-ring-ring/50"
566
+ "tw:hover:not-disabled:bg-primary/10",
567
+ "tw:hover:not-disabled:text-primary",
568
+ "tw:hover:active:bg-background",
569
+ "tw:focus-visible:!border-primary",
570
+ "tw:focus-visible:ring-ring/50"
656
571
  ],
657
572
  // should be called "ghost" by Figma
658
573
  invisible: [
659
- "tw-bg-transparent",
660
- "tw-text-foreground",
661
- "hover:not-disabled:tw-bg-primary/10",
662
- "hover:not-disabled:tw-text-primary",
663
- "hover:not-disabled:tw-border-primary/10",
664
- "focus-visible:tw-ring-ring/50"
574
+ "tw:bg-transparent",
575
+ "tw:text-foreground",
576
+ "tw:hover:not-disabled:bg-primary/10",
577
+ "tw:hover:not-disabled:text-primary",
578
+ "tw:hover:not-disabled:border-primary/10",
579
+ "tw:focus-visible:ring-ring/50"
665
580
  ],
666
581
  // should be called "link" by Figma
667
582
  inline: [
668
- "tw-bg-transparent",
669
- "tw-text-primary",
670
- "hover:tw-underline",
671
- "hover:active:tw-bg-transparent",
672
- "focus-visible:tw-ring-ring/50"
583
+ "tw:bg-transparent",
584
+ "tw:text-primary",
585
+ "tw:hover:underline",
586
+ "tw:hover:active:bg-transparent",
587
+ "tw:focus-visible:ring-ring/50"
673
588
  ]
674
589
  },
675
590
  size: {
676
591
  // should be called "default" by Figma
677
- medium: ["tw-max-h-9", "tw-py-2", "tw-px-4", "tw-text-sm"],
592
+ medium: ["tw:max-h-9", "tw:py-2", "tw:px-4", "tw:text-sm"],
678
593
  // should be called "small" by Figma
679
- small: ["tw-max-h-8", "tw-py-2", "tw-px-3", "tw-text-xs"],
594
+ small: ["tw:max-h-8", "tw:py-2", "tw:px-3", "tw:text-xs"],
680
595
  // should be called "large" by Figma
681
- large: ["tw-max-h-10", "tw-py-2.5", "tw-px-6", "tw-text-sm"],
682
- "icon-lg": ["tw-size-10"],
683
- icon: ["tw-size-9"],
684
- "icon-sm": ["tw-size-8"],
596
+ large: ["tw:max-h-10", "tw:py-2.5", "tw:px-6", "tw:text-sm"],
597
+ "icon-lg": ["tw:size-10"],
598
+ icon: ["tw:size-9"],
599
+ "icon-sm": ["tw:size-8"],
685
600
  // unsupported in ARGO, remove when old design is gone
686
601
  "icon-xs": [],
687
602
  "icon-2xs": [],
@@ -729,13 +644,13 @@ var Button = ({
729
644
  onClick: handleClick,
730
645
  className: cn(classNames),
731
646
  children: [
732
- isLoading && /* @__PURE__ */ jsx(icons_exports.Loader2, { className: "tw-size-4 tw-shrink-0 tw-animate-spin" }),
647
+ isLoading && /* @__PURE__ */ jsx(Loader2, { className: "tw:size-4 tw:shrink-0 tw:animate-spin" }),
733
648
  /* @__PURE__ */ jsx(Slottable, { children: isLoading && isIconOnly ? null : children })
734
649
  ]
735
650
  }
736
651
  );
737
652
  };
738
- var Clipboard = ({
653
+ var Clipboard2 = ({
739
654
  ref,
740
655
  text: textProp,
741
656
  children,
@@ -760,6 +675,7 @@ var Clipboard = ({
760
675
  }
761
676
  };
762
677
  const handleOnClick = (event) => {
678
+ setIsTooltipOpen(true);
763
679
  if (text && state === "ready") void copy(text);
764
680
  onClick?.(event);
765
681
  };
@@ -774,6 +690,7 @@ var Clipboard = ({
774
690
  return tooltip;
775
691
  })();
776
692
  const tooltipVariant = state === "ready" && !!text ? tooltipVariantProp : "action";
693
+ const hasTooltipContent = tooltipContent !== null && tooltipContent !== void 0;
777
694
  return /* @__PURE__ */ jsxs(Tooltip.Root, { open: isTooltipOpen, onOpenChange: handleOnOpenChange, children: [
778
695
  /* @__PURE__ */ jsx(
779
696
  Tooltip.Trigger,
@@ -782,12 +699,12 @@ var Clipboard = ({
782
699
  asChild,
783
700
  keepOpenOnClick: true,
784
701
  onClick: handleOnClick,
785
- className: cn("tw-cursor-pointer", className),
702
+ className: cn("tw:cursor-pointer", className),
786
703
  ref,
787
704
  children: children ?? text
788
705
  }
789
706
  ),
790
- /* @__PURE__ */ jsx(
707
+ hasTooltipContent && /* @__PURE__ */ jsx(
791
708
  Tooltip.Content,
792
709
  {
793
710
  keepOpenOnPointerDownOutside: true,
@@ -798,7 +715,7 @@ var Clipboard = ({
798
715
  )
799
716
  ] });
800
717
  };
801
- var DEFAULT_ICON = /* @__PURE__ */ jsx(icons_exports.Copy, {});
718
+ var DEFAULT_ICON = /* @__PURE__ */ jsx(Copy, {});
802
719
  var DEFAULT_ARIA_LABEL = "Copy";
803
720
  var ClipboardButton = ({
804
721
  // clipboard props
@@ -815,7 +732,7 @@ var ClipboardButton = ({
815
732
  const defaultAriaLabel = typeof tooltip === "string" && tooltip.trim() ? tooltip : DEFAULT_ARIA_LABEL;
816
733
  const ariaLabel = rest["aria-label"] ?? (children == null ? defaultAriaLabel : void 0);
817
734
  return /* @__PURE__ */ jsx(
818
- Clipboard,
735
+ Clipboard2,
819
736
  {
820
737
  asChild: true,
821
738
  tooltip,
@@ -831,13 +748,248 @@ var ClipboardButton = ({
831
748
  };
832
749
  var ButtonToolbar = ({ value, children }) => {
833
750
  if (!value && !children) return null;
834
- return /* @__PURE__ */ 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: [
751
+ return /* @__PURE__ */ 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: [
835
752
  !!value && /* @__PURE__ */ jsx(ClipboardButton, { size: "icon-sm", variant: "invisible", text: value }),
836
753
  children
837
754
  ] });
838
755
  };
756
+ var COMMANDS = [
757
+ "run-operation",
758
+ "run",
759
+ "test",
760
+ "seed",
761
+ "snapshot",
762
+ "list",
763
+ "ls",
764
+ "compile",
765
+ "build",
766
+ "deps",
767
+ "docs",
768
+ "source"
769
+ ];
770
+ var SUBCOMMANDS = { docs: ["generate"], source: ["freshness"] };
771
+ var ARGUMENTS = ["--select", "--exclude", "--selector", "--defer", "--resource-type", "-s"];
772
+ var SELECTORS = ["--select", "--exclude", "-s"];
773
+ var METHODS = [
774
+ "path:",
775
+ "source:",
776
+ "tag:",
777
+ "package:",
778
+ "config:",
779
+ "test_type:",
780
+ "test_name:",
781
+ "state:",
782
+ "exposure:",
783
+ "metric:",
784
+ "result:",
785
+ "source_status:",
786
+ "column_name:"
787
+ ];
788
+ var FLAGS = [
789
+ "--fail-fast",
790
+ "--warn-error",
791
+ "--favor-state",
792
+ "--vars",
793
+ "--models",
794
+ "--threads",
795
+ "--profiles-dir",
796
+ "--profile",
797
+ "--full-refresh"
798
+ ];
799
+ var COMMAND_PHRASES = COMMANDS.flatMap((command) => {
800
+ const subcommands = SUBCOMMANDS[command];
801
+ return subcommands ? subcommands.map((subcommand) => `${command} ${subcommand}`) : [command];
802
+ });
803
+ var alternation = (list) => [...list].sort((a, b) => b.length - a.length).join("|");
804
+ var word = (list) => new RegExp(`^\\s+(?:${alternation(list)})\\b`, "i");
805
+ var prefix = (list) => new RegExp(`^\\s+(?:${alternation(list)})`, "i");
806
+ var WORD = /[\w:-]*$/;
807
+ var asOptions = (list, type) => list.map((label) => ({ label, type }));
808
+ var DBT = [{ label: "dbt", type: "keyword" }];
809
+ var COMMAND_OPTIONS = asOptions(COMMANDS, "keyword");
810
+ var SUBCOMMAND_OPTIONS = Object.fromEntries(
811
+ Object.entries(SUBCOMMANDS).map(([command, subcommands]) => [
812
+ command,
813
+ asOptions(subcommands, "keyword")
814
+ ])
815
+ );
816
+ var ARGUMENT_OPTIONS = asOptions(ARGUMENTS, "variable");
817
+ var FLAG_OPTIONS = asOptions(FLAGS, "constant");
818
+ var METHOD_OPTIONS = asOptions(METHODS, "property");
819
+ var optionsAfter = (words) => {
820
+ const [step, command, ...rest] = words;
821
+ if (step === void 0) return DBT;
822
+ if (step.toLowerCase() !== "dbt") return [];
823
+ if (command === void 0) return COMMAND_OPTIONS;
824
+ const subcommands = SUBCOMMAND_OPTIONS[command.toLowerCase()];
825
+ if (subcommands && rest.length === 0) return subcommands;
826
+ const lastArgument = rest.filter((it) => it.startsWith("-")).at(-1);
827
+ const selecting = lastArgument !== void 0 && SELECTORS.includes(lastArgument.toLowerCase());
828
+ return selecting ? [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS, ...METHOD_OPTIONS] : [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS];
829
+ };
830
+ var complete = (context) => {
831
+ const typed = context.matchBefore(WORD);
832
+ if (!typed?.text && !context.explicit) return null;
833
+ const from = typed?.from ?? context.pos;
834
+ const line = context.state.doc.lineAt(from);
835
+ const options = optionsAfter(
836
+ line.text.slice(0, from - line.from).split(/\s+/).filter(Boolean)
837
+ );
838
+ return options.length > 0 ? { from, options, validFor: WORD } : null;
839
+ };
840
+ var dbt = simpleMode({
841
+ languageData: {
842
+ // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.
843
+ commentTokens: { line: "--", block: { open: "/*", close: "*/" } },
844
+ autocomplete: complete
845
+ },
846
+ start: [
847
+ { regex: /"(?:[^\\]|\\.)*?(?:"|$)/, token: "string" },
848
+ // Word-bounded, so `dbtX` is not a dbt step whose first word happens to
849
+ // colour — the same thing the completion source asks of it.
850
+ { regex: /dbt\b/, token: "keyword", sol: true },
851
+ { regex: word(COMMAND_PHRASES), token: "keyword" },
852
+ { regex: word(ARGUMENTS), token: "variableName" },
853
+ { regex: prefix(METHODS), token: "propertyName" },
854
+ { regex: prefix(FLAGS), token: "attributeName" },
855
+ { regex: /(?:@|\*|,|\+\d+|\d+\+|\+)/, token: "operator" },
856
+ { regex: /'.*'/, token: "string" },
857
+ { regex: /true|false/, token: "atom" }
858
+ ]
859
+ });
860
+
861
+ // src/components/CodeEditor/modes/jsonnet.ts
862
+ var COMMENT_END = /^\*\//;
863
+ var COMMENT_START = /^\/\/|^#/;
864
+ var C_COMMENT_START = /^\/\*/;
865
+ var TEXT_BLOCK = /^\|\|\|/;
866
+ var TEXT_BLOCK_END = /^\s*\|\|\|/;
867
+ var RAW_DOUBLE = /^""/;
868
+ var RAW_SINGLE = /^''/;
869
+ var CLOSE_DOUBLE = /^"/;
870
+ var CLOSE_SINGLE = /^'/;
871
+ var ESCAPE = /^\\[\\"'/bfnrt0]/;
872
+ var UNICODE_ESCAPE = /^\\u[0-9a-fA-F]{4}/;
873
+ var BACKSLASH = /^\\/;
874
+ var IMPORT = /^import(?:str)?\s*(@?)(["'])/;
875
+ var QUOTE = /^(@?)(["'])/;
876
+ var ROOT = /^\$/;
877
+ var NUMBER = /^(?:\.\d+|\d+\.?\d*)(?:e[-+]?\d+)?/i;
878
+ var OPERATOR = /^[-+/*=<>!&~^|$%]+/;
879
+ var IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*/;
880
+ var KEYWORDS = {
881
+ local: "keyword",
882
+ self: "keyword",
883
+ super: "keyword",
884
+ assert: "keyword",
885
+ function: "keyword",
886
+ if: "keyword",
887
+ then: "keyword",
888
+ else: "keyword",
889
+ for: "keyword",
890
+ in: "keyword",
891
+ tailstrict: "keyword",
892
+ error: "keyword",
893
+ true: "atom",
894
+ false: "atom",
895
+ null: "atom"
896
+ };
897
+ var jsonnet = {
898
+ name: "jsonnet",
899
+ // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.
900
+ languageData: { commentTokens: { line: "//", block: { open: "/*", close: "*/" } } },
901
+ startState: () => ({
902
+ cComment: false,
903
+ textBlock: false,
904
+ textBlockIndent: null,
905
+ string: false,
906
+ importString: false,
907
+ stringSingle: false,
908
+ stringRaw: false
909
+ }),
910
+ token: (stream, state) => {
911
+ if (state.cComment) {
912
+ if (stream.match(COMMENT_END)) {
913
+ state.cComment = false;
914
+ return "comment";
915
+ }
916
+ stream.next();
917
+ return "comment";
918
+ }
919
+ if (state.textBlock) {
920
+ if (state.textBlockIndent == null) {
921
+ if (stream.match(TEXT_BLOCK_END)) {
922
+ state.textBlock = false;
923
+ return "string";
924
+ }
925
+ state.textBlockIndent = stream.indentation();
926
+ }
927
+ if (stream.indentation() >= state.textBlockIndent) {
928
+ stream.skipToEnd();
929
+ return "string";
930
+ }
931
+ if (stream.match(TEXT_BLOCK_END)) {
932
+ state.textBlock = false;
933
+ return "string";
934
+ }
935
+ stream.next();
936
+ return "invalid";
937
+ }
938
+ if (state.string || state.importString) {
939
+ const style = state.string ? "string" : "meta";
940
+ if (state.stringRaw) {
941
+ if (stream.match(state.stringSingle ? RAW_SINGLE : RAW_DOUBLE)) return "escape";
942
+ } else {
943
+ if (stream.match(ESCAPE)) return "escape";
944
+ if (stream.match(UNICODE_ESCAPE)) return "escape";
945
+ if (stream.match(BACKSLASH)) return "invalid";
946
+ }
947
+ if (stream.match(state.stringSingle ? CLOSE_SINGLE : CLOSE_DOUBLE)) {
948
+ state.string = false;
949
+ state.importString = false;
950
+ return style;
951
+ }
952
+ stream.next();
953
+ return style;
954
+ }
955
+ if (stream.match(COMMENT_START)) {
956
+ stream.skipToEnd();
957
+ return "comment";
958
+ }
959
+ if (stream.match(C_COMMENT_START)) {
960
+ state.cComment = true;
961
+ return "comment";
962
+ }
963
+ const imported = stream.match(IMPORT);
964
+ if (Array.isArray(imported)) {
965
+ state.importString = true;
966
+ state.stringRaw = imported[1] === "@";
967
+ state.stringSingle = imported[2] === "'";
968
+ return "meta";
969
+ }
970
+ const quoted = stream.match(QUOTE);
971
+ if (Array.isArray(quoted)) {
972
+ state.string = true;
973
+ state.stringRaw = quoted[1] === "@";
974
+ state.stringSingle = quoted[2] === "'";
975
+ return "string";
976
+ }
977
+ if (stream.match(TEXT_BLOCK)) {
978
+ state.textBlock = true;
979
+ state.textBlockIndent = null;
980
+ return "string";
981
+ }
982
+ if (stream.match(ROOT)) return "keyword";
983
+ if (stream.match(NUMBER)) return "number";
984
+ if (stream.match(OPERATOR)) return "operator";
985
+ const identifier = stream.match(IDENTIFIER);
986
+ if (Array.isArray(identifier)) return KEYWORDS[identifier[0]] ?? null;
987
+ stream.next();
988
+ return null;
989
+ }
990
+ };
839
991
  var resolveToken = (token, fallbackChannels, alpha) => {
840
- const channels = typeof document === "undefined" ? fallbackChannels : getComputedStyle(document.documentElement).getPropertyValue(`--color-${token}`).trim() || fallbackChannels;
992
+ const channels = typeof document === "undefined" ? fallbackChannels : getComputedStyle(document.documentElement).getPropertyValue(`--${token}`).trim() || fallbackChannels;
841
993
  return alpha === void 0 ? `rgb(${channels})` : `rgb(${channels} / ${alpha})`;
842
994
  };
843
995
  var SSR_SIGNAL = "ssr";
@@ -857,12 +1009,38 @@ var subscribeThemeSignal = (onChange) => {
857
1009
  return () => observer.disconnect();
858
1010
  };
859
1011
  var useThemeSignal = () => useSyncExternalStore(subscribeThemeSignal, readThemeSignal, () => SSR_SIGNAL);
860
- var useThemedExtension = (build, deps = []) => {
1012
+ var themeCache = /* @__PURE__ */ new Map();
1013
+ var useThemedExtension = (cacheKey, build) => {
861
1014
  const themeSignal = useThemeSignal();
862
- return useMemo(build, [themeSignal, ...deps]);
1015
+ const key = `${themeSignal} ${cacheKey}`;
1016
+ let cached = themeCache.get(key);
1017
+ if (!cached) {
1018
+ cached = build();
1019
+ themeCache.set(key, cached);
1020
+ }
1021
+ return cached;
863
1022
  };
864
1023
 
865
1024
  // src/components/CodeEditor/helpers.ts
1025
+ var LANGUAGE_MODES = [
1026
+ "application/json",
1027
+ "text/plain",
1028
+ "text/x-python",
1029
+ "text/x-sql",
1030
+ "text/x-mysql",
1031
+ "text/x-pgsql",
1032
+ "text/x-mssql",
1033
+ "text/x-sfsql",
1034
+ "text/x-plsql",
1035
+ "text/x-rsrc",
1036
+ "text/x-sh",
1037
+ "text/x-toml",
1038
+ "text/jsonnet",
1039
+ "text/x-dbt",
1040
+ "text/javascript",
1041
+ "text/typescript"
1042
+ ];
1043
+ var isLanguageMode = (mode) => LANGUAGE_MODES.includes(mode);
866
1044
  var buildBaseThemeStyles = () => ({
867
1045
  "*": { lineHeight: "20px" },
868
1046
  "*::selection": {
@@ -903,7 +1081,27 @@ var buildBaseThemeStyles = () => ({
903
1081
  ".cm-changeGutter": { position: "absolute", zIndex: -1, width: "100%", paddingLeft: 0 },
904
1082
  '&[class*="cm-merge-"] .cm-changedLine,&[class*="cm-merge-"] .cm-line, &[class*="cm-merge-"] .cm-deletedChunk': { paddingLeft: 0 }
905
1083
  });
906
- var BASIS_SETUP = { drawSelection: false };
1084
+ var ALWAYS_OFF = {
1085
+ drawSelection: false,
1086
+ foldGutter: false,
1087
+ foldKeymap: false,
1088
+ highlightActiveLine: false,
1089
+ highlightActiveLineGutter: false
1090
+ };
1091
+ var buildBasicSetup = (readOnly) => ({
1092
+ ...ALWAYS_OFF,
1093
+ ...readOnly ? {
1094
+ history: false,
1095
+ historyKeymap: false,
1096
+ closeBrackets: false,
1097
+ closeBracketsKeymap: false,
1098
+ lintKeymap: false,
1099
+ indentOnInput: false,
1100
+ rectangularSelection: false,
1101
+ dropCursor: false,
1102
+ highlightSelectionMatches: false
1103
+ } : null
1104
+ });
907
1105
  var buildCustomTheme = () => githubLightInit({
908
1106
  settings: {
909
1107
  fontFamily: `'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New'`,
@@ -916,37 +1114,175 @@ var buildCustomTheme = () => githubLightInit({
916
1114
  selection: resolveToken("primary", "31 143 255")
917
1115
  }
918
1116
  });
1117
+ var sfsqlWithLanguageData = {
1118
+ ...sfsql,
1119
+ languageData: {
1120
+ ...sfsql.languageData,
1121
+ // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.
1122
+ commentTokens: { line: "--", block: { open: "/*", close: "*/" } },
1123
+ autocomplete: completeFromList(
1124
+ Object.keys(modeSpec.keywords).map((label) => ({
1125
+ label: label.toUpperCase(),
1126
+ type: "keyword"
1127
+ }))
1128
+ )
1129
+ }
1130
+ };
919
1131
  var getLanguageMode = (mode) => {
920
1132
  switch (mode) {
1133
+ case void 0:
1134
+ case "application/json":
1135
+ return json();
921
1136
  case "text/x-python":
922
1137
  return python();
923
1138
  case "text/x-sql":
924
1139
  return sql({ upperCaseKeywords: true });
1140
+ case "text/x-mysql":
1141
+ return sql({ upperCaseKeywords: true, dialect: MySQL });
1142
+ case "text/x-pgsql":
1143
+ return sql({ upperCaseKeywords: true, dialect: PostgreSQL });
1144
+ case "text/x-mssql":
1145
+ return sql({ upperCaseKeywords: true, dialect: MSSQL });
925
1146
  case "text/x-sfsql":
926
- return StreamLanguage.define(sfsql);
1147
+ return StreamLanguage.define(sfsqlWithLanguageData);
927
1148
  case "text/x-plsql":
928
1149
  return sql({ upperCaseKeywords: true, dialect: PLSQL });
929
1150
  case "text/x-rsrc":
930
1151
  return StreamLanguage.define(r);
931
1152
  case "text/x-sh":
932
1153
  return StreamLanguage.define(shell);
1154
+ case "text/x-toml":
1155
+ return StreamLanguage.define(toml);
1156
+ case "text/jsonnet":
1157
+ return StreamLanguage.define(jsonnet);
1158
+ case "text/x-dbt":
1159
+ return StreamLanguage.define(dbt);
933
1160
  case "text/javascript":
934
1161
  return javascript({ jsx: true });
935
1162
  case "text/typescript":
936
1163
  return javascript({ jsx: true, typescript: true });
1164
+ // No language — `text/plain` lands here, and so does any mode added to
1165
+ // LANGUAGE_MODES without an arm above. Unstyled text is the safe degradation;
1166
+ // a `json()` default would colour unrelated content as if it were JSON.
937
1167
  default:
938
- return json();
1168
+ return [];
939
1169
  }
940
1170
  };
941
1171
  var shouldLintJson = (mode, readOnly) => mode === "application/json" && !readOnly;
942
- var KbdSeparator = ({ className, ...props }) => /* @__PURE__ */ jsx("span", { ...props, className: cn("tw-text-xs tw-text-muted-foreground", className) });
1172
+ var setSearchEffect = StateEffect.define();
1173
+ function findMatches(doc, query) {
1174
+ if (!query) return [];
1175
+ const text = doc.toString();
1176
+ try {
1177
+ const regex = new RegExp(escapeStringRegexp(query), "gi");
1178
+ return Array.from(text.matchAll(regex)).map((match, index) => {
1179
+ const from = match.index;
1180
+ const to = from + match[0].length;
1181
+ return { from, to, text: match[0], localIndex: index };
1182
+ });
1183
+ } catch (e) {
1184
+ console.warn("Invalid search regex:", e);
1185
+ return [];
1186
+ }
1187
+ }
1188
+ function createDecorations(matches, selectedLocalIndex) {
1189
+ const decorations = matches.map((match) => {
1190
+ const isSelected = match.localIndex === selectedLocalIndex;
1191
+ const decoration = Decoration.mark({
1192
+ class: isSelected ? "cm-searchMatch-selected" : "cm-searchMatch"
1193
+ });
1194
+ return decoration.range(match.from, match.to);
1195
+ });
1196
+ return Decoration.set(decorations, true);
1197
+ }
1198
+ var searchField = StateField.define({
1199
+ create() {
1200
+ return {
1201
+ query: "",
1202
+ selectedMatchIndex: void 0,
1203
+ matches: [],
1204
+ decorations: Decoration.none
1205
+ };
1206
+ },
1207
+ update(state, tr) {
1208
+ let newState = state;
1209
+ for (const effect of tr.effects) {
1210
+ if (!effect.is(setSearchEffect)) {
1211
+ continue;
1212
+ }
1213
+ const { query, selectedMatchIndex } = effect.value;
1214
+ const matches = findMatches(tr.state.doc, query);
1215
+ const decorations = createDecorations(matches, selectedMatchIndex);
1216
+ newState = {
1217
+ query,
1218
+ selectedMatchIndex,
1219
+ matches,
1220
+ decorations
1221
+ };
1222
+ }
1223
+ if (tr.docChanged && newState.query) {
1224
+ const matches = findMatches(tr.state.doc, newState.query);
1225
+ const decorations = createDecorations(matches, newState.selectedMatchIndex);
1226
+ newState = {
1227
+ ...newState,
1228
+ matches,
1229
+ decorations
1230
+ };
1231
+ }
1232
+ return newState;
1233
+ },
1234
+ provide: (field) => EditorView.decorations.from(field, (state) => state.decorations)
1235
+ });
1236
+ var searchViewPlugin = ViewPlugin.fromClass(
1237
+ class {
1238
+ lastSelectedIndex;
1239
+ update(update) {
1240
+ const state = update.state.field(searchField);
1241
+ if (state.selectedMatchIndex !== void 0 && state.selectedMatchIndex !== this.lastSelectedIndex) {
1242
+ const match = state.matches[state.selectedMatchIndex];
1243
+ if (match) {
1244
+ requestAnimationFrame(() => {
1245
+ update.view.dispatch({
1246
+ effects: EditorView.scrollIntoView(match.from, { y: "center" })
1247
+ });
1248
+ });
1249
+ }
1250
+ this.lastSelectedIndex = state.selectedMatchIndex;
1251
+ }
1252
+ if (state.selectedMatchIndex === void 0) {
1253
+ this.lastSelectedIndex = void 0;
1254
+ }
1255
+ }
1256
+ }
1257
+ );
1258
+ var searchTheme = EditorView.baseTheme({
1259
+ ".cm-searchMatch": {
1260
+ backgroundColor: colors.blue[100]
1261
+ },
1262
+ ".cm-searchMatch > span": {
1263
+ color: `${colors.blue[600]} !important`
1264
+ },
1265
+ ".cm-searchMatch-selected": {
1266
+ backgroundColor: colors.blue[600]
1267
+ },
1268
+ ".cm-searchMatch-selected > span": {
1269
+ color: `${colors.white} !important`
1270
+ }
1271
+ });
1272
+ function searchExtension() {
1273
+ return [searchField, searchViewPlugin, searchTheme];
1274
+ }
1275
+ function updateSearch(view, query, selectedMatchIndex) {
1276
+ view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });
1277
+ }
1278
+ var KbdSeparator = ({ className, ...props }) => /* @__PURE__ */ jsx("span", { ...props, className: cn("tw:text-xs tw:text-muted-foreground", className) });
943
1279
  var KbdGroup = ({ ref, className, children, separator, ...props }) => {
944
1280
  return /* @__PURE__ */ jsx(
945
1281
  "kbd",
946
1282
  {
947
1283
  ...props,
948
1284
  ref,
949
- className: cn("tw-inline-flex", "tw-items-center", "tw-gap-1", className),
1285
+ className: cn("tw:inline-flex", "tw:items-center", "tw:gap-1", className),
950
1286
  children: separator ? (
951
1287
  // oxlint-disable-next-line react-x/no-children-to-array
952
1288
  Children.toArray(children).map((child, index) => (
@@ -964,22 +1300,22 @@ var kbdVariants = cva(
964
1300
  [
965
1301
  "tailwindcss-preflight",
966
1302
  // style
967
- "tw-pointer-events-none",
968
- "tw-w-fit",
969
- "tw-h-5",
970
- "tw-min-w-5",
1303
+ "tw:pointer-events-none",
1304
+ "tw:w-fit",
1305
+ "tw:h-5",
1306
+ "tw:min-w-5",
971
1307
  // layout
972
- "tw-inline-flex",
973
- "tw-items-center",
974
- "tw-justify-center",
975
- "tw-gap-1",
976
- "tw-shrink-0",
1308
+ "tw:inline-flex",
1309
+ "tw:items-center",
1310
+ "tw:justify-center",
1311
+ "tw:gap-1",
1312
+ "tw:shrink-0",
977
1313
  // spacing
978
- "tw-px-1",
979
- '[&_svg:not([class*="size-"])]:tw-size-2.5',
980
- "tw-text-xs",
981
- "tw-font-medium",
982
- "tw-rounded"
1314
+ "tw:px-1",
1315
+ 'tw:[&_svg:not([class*="size-"])]:size-2.5',
1316
+ "tw:text-xs",
1317
+ "tw:font-medium",
1318
+ "tw:rounded"
983
1319
  ],
984
1320
  {
985
1321
  defaultVariants: {
@@ -987,8 +1323,8 @@ var kbdVariants = cva(
987
1323
  },
988
1324
  variants: {
989
1325
  variant: {
990
- default: "tw-bg-muted tw-text-muted-foreground",
991
- primary: "tw-bg-white/20 tw-text-white"
1326
+ default: "tw:bg-muted tw:text-muted-foreground",
1327
+ primary: "tw:bg-white/20 tw:text-white"
992
1328
  }
993
1329
  }
994
1330
  }
@@ -998,11 +1334,78 @@ Kbd.Group = KbdGroup;
998
1334
  Kbd.Separator = KbdSeparator;
999
1335
  var ToggleComponentHelp = () => /* @__PURE__ */ jsxs("div", { children: [
1000
1336
  "Use ",
1001
- /* @__PURE__ */ jsx(Kbd, { children: "Ctrl+/" }),
1002
- " or ",
1003
- /* @__PURE__ */ jsx(Kbd, { children: "Command+/" }),
1337
+ /* @__PURE__ */ jsx(Kbd, { children: isMac ? "Command+/" : "Ctrl+/" }),
1004
1338
  " to toggle comments."
1005
1339
  ] });
1340
+ 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);
1341
+ var crops = (style) => style.overflowX !== "visible" || style.overflowY !== "visible" || style.maskImage !== "none" || style.contentVisibility !== "visible" || /\b(paint|strict|content)\b/.test(style.contain);
1342
+ var findTooltipHost = (from) => {
1343
+ let outermostCropper = null;
1344
+ for (let node = from.parentElement; node && node !== document.body; node = node.parentElement) {
1345
+ const style = getComputedStyle(node);
1346
+ if (crops(style)) {
1347
+ outermostCropper = node;
1348
+ } else if (establishesFixedContainingBlock(style)) {
1349
+ return outermostCropper?.parentElement ?? node;
1350
+ }
1351
+ }
1352
+ return outermostCropper?.parentElement ?? null;
1353
+ };
1354
+ var tooltipsExtension = () => {
1355
+ const layer = new Compartment();
1356
+ return [
1357
+ layer.of(tooltips()),
1358
+ ViewPlugin.define((view) => {
1359
+ const scheduled = setTimeout(() => {
1360
+ if (!view.dom.isConnected) return;
1361
+ const parent = findTooltipHost(view.dom);
1362
+ if (parent) view.dispatch({ effects: layer.reconfigure(tooltips({ parent })) });
1363
+ });
1364
+ return { destroy: () => clearTimeout(scheduled) };
1365
+ })
1366
+ ];
1367
+ };
1368
+ var useTooltipsExtension = () => useMemo(tooltipsExtension, []);
1369
+
1370
+ // src/components/CodeEditor/variableCompletion.ts
1371
+ var BOOST = 2e3;
1372
+ var NAME = String.raw`[\w-]*`;
1373
+ var AT_CARET = new RegExp(String.raw`(?:\{{1,2} ?)?${NAME}$`);
1374
+ var NAME_AT_END = new RegExp(`${NAME}$`);
1375
+ var OPENING = /\{{1,2} ?$/;
1376
+ var CLOSING = /^ ?\}{1,2}/;
1377
+ var completeVariables = (variables = []) => {
1378
+ if (variables.length === 0) return () => null;
1379
+ const options = variables.map(({ name, value }) => ({
1380
+ // The bare name: `SqlEditor` filters prefix-only while `CodeEditor` filters
1381
+ // fuzzily, and this is the only spelling both accept whether or not the caret
1382
+ // has typed the braces. The braces are `displayLabel`, which is what renders.
1383
+ label: name,
1384
+ displayLabel: `{{${name}}}`,
1385
+ detail: value,
1386
+ type: "variable",
1387
+ boost: BOOST,
1388
+ apply: (view, completion, from, to) => {
1389
+ const { doc } = view.state;
1390
+ const line = doc.lineAt(from);
1391
+ const insert = `{{${completion.label}}}`;
1392
+ const opening = OPENING.exec(doc.sliceString(line.from, from));
1393
+ const closing = CLOSING.exec(doc.sliceString(to, line.to));
1394
+ const start = opening ? from - opening[0].length : from;
1395
+ const end = closing ? to + closing[0].length : to;
1396
+ view.dispatch({
1397
+ changes: { from: start, to: end, insert },
1398
+ selection: { anchor: start + insert.length }
1399
+ });
1400
+ }
1401
+ }));
1402
+ return (context) => {
1403
+ const match = context.matchBefore(AT_CARET);
1404
+ if (!match?.text) return null;
1405
+ const [name = ""] = NAME_AT_END.exec(match.text) ?? [];
1406
+ return { from: match.to - name.length, options };
1407
+ };
1408
+ };
1006
1409
  var emptyArray = [];
1007
1410
  var emptyObject = {};
1008
1411
  var CodeEditor = ({
@@ -1011,45 +1414,96 @@ var CodeEditor = ({
1011
1414
  onChange,
1012
1415
  mode = "application/json",
1013
1416
  placeholder: placeholder$1 = "",
1417
+ ariaLabel,
1418
+ searchQuery,
1419
+ searchMatchIndex,
1014
1420
  readOnly = false,
1015
1421
  autocompletions = emptyArray,
1422
+ completionSource,
1423
+ variables,
1016
1424
  extraKeys = emptyObject,
1017
1425
  withToggleCommentHint = false,
1018
1426
  withAutofocus = false,
1019
1427
  withLineNumbers = true,
1020
1428
  withLineWrapping = true,
1021
1429
  withCollapseUnchanged = false,
1022
- withCopyButton = true,
1430
+ withCopyButton = false,
1023
1431
  completeAny = false,
1024
1432
  help = null,
1025
1433
  helpPostfix = null,
1026
1434
  renderAdditionalButtons,
1027
1435
  className
1028
1436
  }) => {
1029
- const customTheme = useThemedExtension(buildCustomTheme);
1030
- const baseTheme = useThemedExtension(() => EditorView.theme(buildBaseThemeStyles()));
1437
+ const handleChange = useStableCallback((next) => onChange?.(next));
1438
+ const withSearch = searchQuery !== void 0;
1439
+ const editorRef = useRef(null);
1440
+ useEffect(() => {
1441
+ const view = editorRef.current?.view;
1442
+ if (view && withSearch) updateSearch(view, searchQuery, searchMatchIndex);
1443
+ }, [withSearch, searchQuery, searchMatchIndex]);
1444
+ const handleCreateEditor = useStableCallback((view) => {
1445
+ if (searchQuery) updateSearch(view, searchQuery, searchMatchIndex);
1446
+ });
1447
+ const extraKeysRef = useRef(extraKeys);
1448
+ useLayoutEffect(() => {
1449
+ extraKeysRef.current = extraKeys;
1450
+ });
1451
+ const boundKeysSignature = Object.keys(extraKeys).join("\n");
1452
+ const boundKeys = useMemo(
1453
+ () => boundKeysSignature.split("\n").filter(Boolean),
1454
+ [boundKeysSignature]
1455
+ );
1456
+ const tooltipLayer = useTooltipsExtension();
1457
+ const variableCompletion = useMemo(() => completeVariables(variables), [variables]);
1458
+ const customTheme = useThemedExtension("editor:syntax", buildCustomTheme);
1459
+ const baseTheme = useThemedExtension(
1460
+ "code-editor:chrome",
1461
+ () => EditorView.theme(buildBaseThemeStyles())
1462
+ );
1031
1463
  const commonExtensions = useMemo(() => {
1032
1464
  return [
1033
1465
  getLanguageMode(mode),
1034
- shouldLintJson(mode, readOnly) && linter(jsonParseLinter()),
1466
+ shouldLintJson(mode, readOnly) ? linter(jsonParseLinter()) : [],
1035
1467
  withLineWrapping ? EditorView.lineWrapping : [],
1036
1468
  EditorState.languageData.of(() => [
1037
- { autocomplete: completeAny ? completeAnyWord : autocompletions }
1469
+ { autocomplete: completionSource ?? (completeAny ? completeAnyWord : autocompletions) }
1038
1470
  ]),
1471
+ EditorState.languageData.of(() => [{ autocomplete: variableCompletion }]),
1039
1472
  keymap.of(
1040
- Object.entries(extraKeys).map(([key, run]) => ({
1473
+ boundKeys.map((key) => ({
1041
1474
  key,
1042
1475
  run: () => {
1043
- if (typeof run === "string") return run;
1044
- run();
1476
+ extraKeysRef.current[key]?.();
1045
1477
  return true;
1046
1478
  }
1047
1479
  }))
1048
1480
  ),
1049
- autocompletion({ activateOnTyping: completeAny }),
1481
+ readOnly ? [] : [
1482
+ // CodeMirror's own default. Gating it on the props hid completions the
1483
+ // *language* supplies — dbt's vocabulary, Snowflake's keywords — behind
1484
+ // a shortcut, and macOS leaves no usable one. With nothing to offer, no
1485
+ // popup opens anyway.
1486
+ autocompletion()
1487
+ ],
1488
+ ariaLabel ? EditorView.contentAttributes.of({ "aria-label": ariaLabel }) : [],
1489
+ withSearch ? searchExtension() : [],
1490
+ tooltipLayer,
1050
1491
  baseTheme
1051
- ].filter(Boolean);
1052
- }, [autocompletions, completeAny, extraKeys, mode, readOnly, withLineWrapping, baseTheme]);
1492
+ ];
1493
+ }, [
1494
+ autocompletions,
1495
+ completionSource,
1496
+ variableCompletion,
1497
+ completeAny,
1498
+ boundKeys,
1499
+ mode,
1500
+ readOnly,
1501
+ withLineWrapping,
1502
+ baseTheme,
1503
+ ariaLabel,
1504
+ withSearch,
1505
+ tooltipLayer
1506
+ ]);
1053
1507
  const extensions = useMemo(() => {
1054
1508
  return [
1055
1509
  ...commonExtensions,
@@ -1066,18 +1520,23 @@ var CodeEditor = ({
1066
1520
  }, [commonExtensions, placeholder$1, readOnly, previousValue, withCollapseUnchanged]);
1067
1521
  const config = useMemo(() => {
1068
1522
  return {
1069
- ...BASIS_SETUP,
1070
- lineNumbers: withLineNumbers
1523
+ ...buildBasicSetup(readOnly),
1524
+ lineNumbers: withLineNumbers,
1525
+ // Mod-f opens CodeMirror's own panel, which would run a second query and a
1526
+ // second match count over the same document beside the caller's input.
1527
+ ...withSearch ? { searchKeymap: false } : null
1071
1528
  };
1072
- }, [withLineNumbers]);
1529
+ }, [withLineNumbers, readOnly, withSearch]);
1530
+ const additionalButtons = renderAdditionalButtons?.(value);
1531
+ const hasToolbar = withCopyButton && !!value || !!additionalButtons;
1073
1532
  return (
1074
1533
  // oxlint-disable-next-line jsx-a11y/no-static-element-interactions
1075
1534
  /* @__PURE__ */ jsxs(
1076
1535
  "div",
1077
1536
  {
1078
1537
  className: cn(
1079
- "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",
1080
- { "tw-mt-5": !!renderAdditionalButtons },
1538
+ "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",
1539
+ { "tw:mt-8": hasToolbar },
1081
1540
  className
1082
1541
  ),
1083
1542
  onKeyDown: (event) => {
@@ -1086,19 +1545,21 @@ var CodeEditor = ({
1086
1545
  }
1087
1546
  },
1088
1547
  children: [
1089
- (withCopyButton || renderAdditionalButtons) && /* @__PURE__ */ 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__ */ jsx("div", { className: "tw-flex-1", children: /* @__PURE__ */ jsx(ButtonToolbar, { value: withCopyButton ? value : void 0, children: renderAdditionalButtons?.(value) }) }) }),
1548
+ hasToolbar && /* @__PURE__ */ 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__ */ jsx("div", { className: "tw:flex-1", children: /* @__PURE__ */ jsx(ButtonToolbar, { value: withCopyButton ? value : void 0, children: additionalButtons }) }) }),
1090
1549
  /* @__PURE__ */ jsx(
1091
1550
  CodeMirror,
1092
1551
  {
1552
+ ref: editorRef,
1553
+ onCreateEditor: handleCreateEditor,
1093
1554
  theme: customTheme,
1094
1555
  value,
1095
- onChange,
1556
+ onChange: handleChange,
1096
1557
  extensions,
1097
1558
  autoFocus: withAutofocus,
1098
1559
  basicSetup: config
1099
1560
  }
1100
1561
  ),
1101
- !readOnly && (withToggleCommentHint || help || helpPostfix) && /* @__PURE__ */ jsxs(HelpBlock, { className: "tw-mt-2 tw-flex tw-flex-wrap tw-gap-1", children: [
1562
+ !readOnly && (withToggleCommentHint || help || helpPostfix) && /* @__PURE__ */ jsxs(HelpBlock, { className: "tw:mt-2 tw:flex tw:flex-wrap tw:gap-1", children: [
1102
1563
  help,
1103
1564
  withToggleCommentHint ? /* @__PURE__ */ jsx(ToggleComponentHelp, {}) : null,
1104
1565
  helpPostfix
@@ -1412,114 +1873,7 @@ function highlightingExtension(queryParser) {
1412
1873
  function updateHighlighting(view, lines) {
1413
1874
  view.dispatch({ effects: setHighlightedLinesEffect.of(lines ?? null) });
1414
1875
  }
1415
- var setSearchEffect = StateEffect.define();
1416
- function findMatches(doc, query) {
1417
- if (!query) return [];
1418
- const text = doc.toString();
1419
- try {
1420
- const regex = new RegExp(escapeStringRegexp(query), "gi");
1421
- return Array.from(text.matchAll(regex)).map((match, index) => {
1422
- const from = match.index;
1423
- const to = from + match[0].length;
1424
- return { from, to, text: match[0], localIndex: index };
1425
- });
1426
- } catch (e) {
1427
- console.warn("Invalid search regex:", e);
1428
- return [];
1429
- }
1430
- }
1431
- function createDecorations(matches, selectedLocalIndex) {
1432
- const decorations = matches.map((match) => {
1433
- const isSelected = match.localIndex === selectedLocalIndex;
1434
- const decoration = Decoration.mark({
1435
- class: isSelected ? "cm-searchMatch-selected" : "cm-searchMatch"
1436
- });
1437
- return decoration.range(match.from, match.to);
1438
- });
1439
- return Decoration.set(decorations, true);
1440
- }
1441
- var searchField = StateField.define({
1442
- create() {
1443
- return {
1444
- query: "",
1445
- selectedMatchIndex: void 0,
1446
- matches: [],
1447
- decorations: Decoration.none
1448
- };
1449
- },
1450
- update(state, tr) {
1451
- let newState = state;
1452
- for (const effect of tr.effects) {
1453
- if (!effect.is(setSearchEffect)) {
1454
- continue;
1455
- }
1456
- const { query, selectedMatchIndex } = effect.value;
1457
- const matches = findMatches(tr.state.doc, query);
1458
- const decorations = createDecorations(matches, selectedMatchIndex);
1459
- newState = {
1460
- query,
1461
- selectedMatchIndex,
1462
- matches,
1463
- decorations
1464
- };
1465
- }
1466
- if (tr.docChanged && newState.query) {
1467
- const matches = findMatches(tr.state.doc, newState.query);
1468
- const decorations = createDecorations(matches, newState.selectedMatchIndex);
1469
- newState = {
1470
- ...newState,
1471
- matches,
1472
- decorations
1473
- };
1474
- }
1475
- return newState;
1476
- },
1477
- provide: (field) => EditorView.decorations.from(field, (state) => state.decorations)
1478
- });
1479
- var searchViewPlugin = ViewPlugin.fromClass(
1480
- class {
1481
- lastSelectedIndex;
1482
- update(update) {
1483
- const state = update.state.field(searchField);
1484
- if (state.selectedMatchIndex !== void 0 && state.selectedMatchIndex !== this.lastSelectedIndex) {
1485
- const match = state.matches[state.selectedMatchIndex];
1486
- if (match) {
1487
- requestAnimationFrame(() => {
1488
- update.view.dispatch({
1489
- effects: EditorView.scrollIntoView(match.from, { y: "center" })
1490
- });
1491
- });
1492
- }
1493
- this.lastSelectedIndex = state.selectedMatchIndex;
1494
- }
1495
- if (state.selectedMatchIndex === void 0) {
1496
- this.lastSelectedIndex = void 0;
1497
- }
1498
- }
1499
- }
1500
- );
1501
- var searchTheme = EditorView.baseTheme({
1502
- ".cm-searchMatch": {
1503
- backgroundColor: colors.blue[100]
1504
- },
1505
- ".cm-searchMatch > span": {
1506
- color: `${colors.blue[600]} !important`
1507
- },
1508
- ".cm-searchMatch-selected": {
1509
- backgroundColor: colors.blue[600]
1510
- },
1511
- ".cm-searchMatch-selected > span": {
1512
- color: `${colors.white} !important`
1513
- }
1514
- });
1515
- function searchExtension() {
1516
- return [searchField, searchViewPlugin, searchTheme];
1517
- }
1518
- function updateSearch(view, query, selectedMatchIndex) {
1519
- view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });
1520
- }
1521
- var BASIS_SETUP2 = {
1522
- drawSelection: false,
1876
+ var OWN_KEYMAPS = {
1523
1877
  defaultKeymap: false,
1524
1878
  completionKeymap: false,
1525
1879
  searchKeymap: false
@@ -1584,16 +1938,27 @@ var SqlEditor = ({
1584
1938
  dialect
1585
1939
  }) => {
1586
1940
  const editorRef = useRef(null);
1587
- const customTheme = useThemedExtension(buildCustomTheme);
1588
- const themeExtension = useThemedExtension(() => EditorView$1.theme(buildTheme()));
1941
+ const tooltipLayer = useTooltipsExtension();
1942
+ const customTheme = useThemedExtension("editor:syntax", buildCustomTheme);
1943
+ const themeExtension = useThemedExtension(
1944
+ "sql-editor:chrome",
1945
+ () => EditorView$1.theme(buildTheme())
1946
+ );
1589
1947
  const extensions = useMemo(() => {
1590
1948
  const baseKeymap = [...defaultKeymap, ...CUSTOM_KEYMAP];
1591
1949
  return [
1592
1950
  EditorView$1.lineWrapping,
1593
1951
  keymap$1.of(extraKeys ? [...extraKeys, ...baseKeymap] : baseKeymap),
1594
- ...installExtensions({ schema, defaultDatabase, defaultSchema, variables, dialect }),
1952
+ ...installExtensions({
1953
+ schema,
1954
+ defaultDatabase,
1955
+ defaultSchema,
1956
+ variableCompletion: completeVariables(variables),
1957
+ dialect
1958
+ }),
1595
1959
  searchExtension(),
1596
1960
  highlightingExtension(queryParser),
1961
+ tooltipLayer,
1597
1962
  themeExtension,
1598
1963
  onBlurEditor ? EditorView$1.domEventHandlers({ blur: (_, view) => onBlurEditor(view) }) : [],
1599
1964
  onFocusEditor ? EditorView$1.domEventHandlers({ focus: (_, view) => onFocusEditor(view) }) : []
@@ -1608,11 +1973,12 @@ var SqlEditor = ({
1608
1973
  dialect,
1609
1974
  onBlurEditor,
1610
1975
  onFocusEditor,
1611
- themeExtension
1976
+ themeExtension,
1977
+ tooltipLayer
1612
1978
  ]);
1613
1979
  const defaultSetup = useMemo(() => {
1614
- return { ...BASIS_SETUP2, lineNumbers };
1615
- }, [lineNumbers]);
1980
+ return { ...buildBasicSetup(readOnly), ...OWN_KEYMAPS, lineNumbers };
1981
+ }, [readOnly, lineNumbers]);
1616
1982
  useEffect(() => {
1617
1983
  if (editorRef.current?.view) {
1618
1984
  updateHighlighting(editorRef.current.view, highlightLines);
@@ -1678,25 +2044,25 @@ var LINE_HEIGHT_PX = 20;
1678
2044
  var PANE_HEADER_HEIGHT_PX = 58;
1679
2045
  var AcceptButton = ({ side, onAccept }) => {
1680
2046
  const label = `Accept ${side === "left" ? "production" : "branch"} version`;
1681
- const Chevron = side === "left" ? icons_exports.ChevronsRight : icons_exports.ChevronsLeft;
1682
- return /* @__PURE__ */ jsx(Button, { onClick: onAccept, variant: "outline", size: "icon-sm", title: label, "aria-label": label, children: /* @__PURE__ */ jsx(Chevron, { className: "tw-size-5" }) });
2047
+ const Chevron = side === "left" ? ChevronsRight : ChevronsLeft;
2048
+ return /* @__PURE__ */ jsx(Button, { onClick: onAccept, variant: "outline", size: "icon-sm", title: label, "aria-label": label, children: /* @__PURE__ */ jsx(Chevron, { className: "tw:size-5" }) });
1683
2049
  };
1684
2050
  var AcceptControls = ({ conflicts, side, onAccept, onDismiss, contentRef }) => /* @__PURE__ */ jsx(
1685
2051
  "div",
1686
2052
  {
1687
2053
  className: cn(
1688
- "tw-z-10 tw-flex tw-shrink-0 tw-flex-col tw-items-center",
1689
- conflicts.length > 0 ? "tw-w-7" : "tw-w-0"
2054
+ "tw:z-10 tw:flex tw:shrink-0 tw:flex-col tw:items-center",
2055
+ conflicts.length > 0 ? "tw:w-7" : "tw:w-0"
1690
2056
  ),
1691
2057
  children: conflicts.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
1692
- /* @__PURE__ */ jsx("div", { className: "tw-shrink-0", style: { height: `${PANE_HEADER_HEIGHT_PX}px` } }),
1693
- /* @__PURE__ */ jsx("div", { className: "tw-relative tw-w-full tw-flex-1 tw-overflow-y-clip tw-overflow-x-visible", children: /* @__PURE__ */ jsx("div", { ref: contentRef, className: "tw-relative tw-size-full", children: conflicts.map((conflict) => {
2058
+ /* @__PURE__ */ jsx("div", { className: "tw:shrink-0", style: { height: `${PANE_HEADER_HEIGHT_PX}px` } }),
2059
+ /* @__PURE__ */ jsx("div", { className: "tw:relative tw:w-full tw:flex-1 tw:overflow-y-clip tw:overflow-x-visible", children: /* @__PURE__ */ jsx("div", { ref: contentRef, className: "tw:relative tw:size-full", children: conflicts.map((conflict) => {
1694
2060
  const topLine = side === "left" ? conflict.oldStartLine : conflict.newStartLine;
1695
2061
  const topOffset = (topLine - 1) * LINE_HEIGHT_PX - 2;
1696
2062
  return /* @__PURE__ */ jsxs(
1697
2063
  "div",
1698
2064
  {
1699
- className: "tw-absolute tw-inset-x-0 tw-flex tw-flex-col tw-items-center tw-gap-0.5",
2065
+ className: "tw:absolute tw:inset-x-0 tw:flex tw:flex-col tw:items-center tw:gap-0.5",
1700
2066
  style: { top: `${topOffset}px` },
1701
2067
  children: [
1702
2068
  /* @__PURE__ */ jsx(AcceptButton, { side, onAccept: () => onAccept(conflict) }),
@@ -1708,7 +2074,7 @@ var AcceptControls = ({ conflicts, side, onAccept, onDismiss, contentRef }) => /
1708
2074
  size: "icon-sm",
1709
2075
  title: "Dismiss",
1710
2076
  "aria-label": `Dismiss ${side === "left" ? "production" : "branch"} change`,
1711
- children: /* @__PURE__ */ jsx(icons_exports.X, { className: "tw-size-4" })
2077
+ children: /* @__PURE__ */ jsx(X, { className: "tw:size-4" })
1712
2078
  }
1713
2079
  )
1714
2080
  ]
@@ -1805,13 +2171,15 @@ var MergePane = ({
1805
2171
  deleted = false
1806
2172
  }) => {
1807
2173
  const editorRef = useRef(null);
2174
+ const handleChange = useStableCallback((next) => onChange?.(next));
1808
2175
  const themeExtension = useThemedExtension(
2176
+ `merge-pane:${deleted}`,
1809
2177
  () => EditorView.theme({
1810
2178
  "&.cm-editor": {
1811
2179
  height: "100%",
1812
2180
  backgroundColor: deleted ? colors.error[100] : resolveToken("background", "249 250 251"),
1813
2181
  // Pair the token-driven surface with a token-driven text color so line
1814
- // content stays readable when the pane's `--color-background` goes dark.
2182
+ // content stays readable when the pane's `--background` goes dark.
1815
2183
  // The deleted pane keeps default dark text on its fixed light-red wash.
1816
2184
  ...deleted ? {} : { color: resolveToken("foreground", "30 41 59") },
1817
2185
  outline: "none"
@@ -1822,10 +2190,13 @@ var MergePane = ({
1822
2190
  },
1823
2191
  "*": { lineHeight: `${LINE_HEIGHT_PX}px` },
1824
2192
  ".cm-lineNumbers .cm-gutterElement": { padding: "0 0 0 25px" }
1825
- }),
1826
- [deleted]
2193
+ })
1827
2194
  );
1828
2195
  const diffHighlightExtension = useMemo(() => createDiffHighlightExtension(), []);
2196
+ const basicSetup = useMemo(
2197
+ () => ({ ...buildBasicSetup(readOnly), lineNumbers: true }),
2198
+ [readOnly]
2199
+ );
1829
2200
  const extensions = useMemo(
1830
2201
  () => [
1831
2202
  diffHighlightExtension,
@@ -1875,33 +2246,33 @@ var MergePane = ({
1875
2246
  "div",
1876
2247
  {
1877
2248
  className: cn(
1878
- "tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-overflow-hidden",
2249
+ "tw:flex tw:min-w-0 tw:flex-1 tw:flex-col tw:overflow-hidden",
1879
2250
  className,
1880
- deleted && "tw-border-error-300"
2251
+ deleted && "tw:border-error-300"
1881
2252
  ),
1882
2253
  children: [
1883
2254
  header && /* @__PURE__ */ jsx(
1884
2255
  "div",
1885
2256
  {
1886
2257
  className: cn(
1887
- "tw-px-4 tw-py-3",
1888
- deleted ? "tw-border-b tw-border-error-200 tw-bg-error-100" : "tw-bg-background",
2258
+ "tw:px-4 tw:py-3",
2259
+ deleted ? "tw:border-b tw:border-error-200 tw:bg-error-100" : "tw:bg-background",
1889
2260
  headerClassName
1890
2261
  ),
1891
2262
  children: header
1892
2263
  }
1893
2264
  ),
1894
- /* @__PURE__ */ jsx("div", { className: "tw-flex tw-h-0 tw-flex-1 tw-flex-col [&_>div]:tw-h-full", children: /* @__PURE__ */ jsx(
2265
+ /* @__PURE__ */ jsx("div", { className: "tw:flex tw:h-0 tw:flex-1 tw:flex-col tw:[&_>div]:h-full", children: /* @__PURE__ */ jsx(
1895
2266
  CodeMirror,
1896
2267
  {
1897
2268
  ref: editorRef,
1898
2269
  height: "100%",
1899
2270
  value,
1900
- onChange,
2271
+ onChange: handleChange,
1901
2272
  extensions,
1902
2273
  readOnly,
1903
2274
  onCreateEditor: handleCreateEditor,
1904
- basicSetup: { lineNumbers: true, drawSelection: false }
2275
+ basicSetup
1905
2276
  }
1906
2277
  ) })
1907
2278
  ]
@@ -2001,7 +2372,7 @@ var MergeEditor = ({
2001
2372
  "div",
2002
2373
  {
2003
2374
  className: cn(
2004
- "tw-flex tw-h-full tw-min-h-0 tw-overflow-hidden tw-bg-background tw-gap-3",
2375
+ "tw:flex tw:h-full tw:min-h-0 tw:overflow-hidden tw:bg-background tw:gap-3",
2005
2376
  className
2006
2377
  ),
2007
2378
  children: [
@@ -2013,7 +2384,7 @@ var MergeEditor = ({
2013
2384
  lineClassification: leftClassification,
2014
2385
  readOnly: true,
2015
2386
  header: leftHeader,
2016
- className: "tw-rounded-r-lg tw-border tw-border-border",
2387
+ className: "tw:rounded-r-lg tw:border tw:border-border",
2017
2388
  onScrollDOMReady: registerScroller(0),
2018
2389
  deleted: leftDeleted
2019
2390
  }
@@ -2037,7 +2408,7 @@ var MergeEditor = ({
2037
2408
  onChange: handleMergeChange,
2038
2409
  header: middleHeader,
2039
2410
  headerClassName: middleHeaderClassName,
2040
- className: cn("tw-border tw-border-border tw-rounded-lg", middleClassName),
2411
+ className: cn("tw:border tw:border-border tw:rounded-lg", middleClassName),
2041
2412
  onScrollDOMReady: registerScroller(1)
2042
2413
  }
2043
2414
  ),
@@ -2059,7 +2430,7 @@ var MergeEditor = ({
2059
2430
  lineClassification: rightClassification,
2060
2431
  readOnly: true,
2061
2432
  header: rightHeader,
2062
- className: "tw-rounded-l-lg tw-border tw-border-border",
2433
+ className: "tw:rounded-l-lg tw:border tw:border-border",
2063
2434
  onScrollDOMReady: registerScroller(2),
2064
2435
  deleted: rightDeleted
2065
2436
  }
@@ -2069,6 +2440,6 @@ var MergeEditor = ({
2069
2440
  );
2070
2441
  };
2071
2442
 
2072
- export { CodeEditor, MergeEditor, SqlEditor };
2443
+ export { CodeEditor, LANGUAGE_MODES, MergeEditor, SqlEditor, isLanguageMode };
2073
2444
  //# sourceMappingURL=editors.js.map
2074
2445
  //# sourceMappingURL=editors.js.map