@keboola/design 3.2.3 → 4.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.
package/dist/index.cjs CHANGED
@@ -39,27 +39,9 @@ var ResizablePrimitive = require('react-resizable-panels');
39
39
  var RadixAvatar = require('@radix-ui/react-avatar');
40
40
  var RadixTabs = require('@radix-ui/react-tabs');
41
41
  var diff = require('diff');
42
- var view = require('@codemirror/view');
43
- var CodeMirror = require('@uiw/react-codemirror');
44
- var colors3 = require('@keboola/tailwind-config/colors');
45
- var state = require('@codemirror/state');
46
42
  var nodeDiff3 = require('node-diff3');
47
43
  var reactForm = require('@tanstack/react-form');
48
44
  var DOMPurify = require('dompurify');
49
- var autocomplete = require('@codemirror/autocomplete');
50
- var langJson = require('@codemirror/lang-json');
51
- var lint = require('@codemirror/lint');
52
- var merge = require('@codemirror/merge');
53
- var langJavascript = require('@codemirror/lang-javascript');
54
- var langPython = require('@codemirror/lang-python');
55
- var langSql = require('@codemirror/lang-sql');
56
- var language = require('@codemirror/language');
57
- var r = require('@codemirror/legacy-modes/mode/r');
58
- var shell = require('@codemirror/legacy-modes/mode/shell');
59
- var codemirrorThemeGithub = require('@uiw/codemirror-theme-github');
60
- var codemirrorLangSfsql = require('@keboola/codemirror-lang-sfsql');
61
- var commands = require('@codemirror/commands');
62
- var codemirrorLangSql = require('@keboola/codemirror-lang-sql');
63
45
 
64
46
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
65
47
 
@@ -95,8 +77,6 @@ var BoringAvatar__default = /*#__PURE__*/_interopDefault(BoringAvatar);
95
77
  var ResizablePrimitive__namespace = /*#__PURE__*/_interopNamespace(ResizablePrimitive);
96
78
  var RadixAvatar__namespace = /*#__PURE__*/_interopNamespace(RadixAvatar);
97
79
  var RadixTabs__namespace = /*#__PURE__*/_interopNamespace(RadixTabs);
98
- var CodeMirror__default = /*#__PURE__*/_interopDefault(CodeMirror);
99
- var colors3__default = /*#__PURE__*/_interopDefault(colors3);
100
80
  var DOMPurify__default = /*#__PURE__*/_interopDefault(DOMPurify);
101
81
 
102
82
  var __defProp = Object.defineProperty;
@@ -168,7 +148,6 @@ var createChangeInputEvent = (input) => {
168
148
  // src/constants/keyCodes.ts
169
149
  var keyCodes = {
170
150
  ENTER: "Enter",
171
- ESCAPE: "Escape",
172
151
  SPACE: " "
173
152
  };
174
153
  var ThemeContext = react.createContext(null);
@@ -6904,8 +6883,8 @@ var coerceColorPickerValue = (value) => {
6904
6883
  const body = extractHexBody(value);
6905
6884
  if (body === null || !HEX_CHARSET.test(body)) return PICKER_FALLBACK;
6906
6885
  if (body.length === 3 || body.length === 4) {
6907
- const [r2, g, b] = body;
6908
- return `#${r2}${r2}${g}${g}${b}${b}`.toLowerCase();
6886
+ const [r, g, b] = body;
6887
+ return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();
6909
6888
  }
6910
6889
  if (body.length === 6 || body.length === 8) {
6911
6890
  return `#${body.slice(0, 6).toLowerCase()}`;
@@ -9346,7 +9325,11 @@ var AlertRoot = ({
9346
9325
  "has-[[data-slot=alert-icon]]:tw-gap-x-2",
9347
9326
  // fonts
9348
9327
  "tw-text-sm",
9328
+ // Legacy keeps the fixed neutral text; argo uses the semantic foreground
9329
+ // so the alert flips with the brand's light/dark palette (the categorical
9330
+ // variant tint stays — only the text token becomes brand-aware).
9349
9331
  "tw-text-neutral-800",
9332
+ "data-[argo=true]:tw-text-foreground",
9350
9333
  "tw-text-left",
9351
9334
  "tw-p-4",
9352
9335
  // border
@@ -10320,20 +10303,20 @@ var AIGradientsSvg = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "0", h
10320
10303
  // src/components/ThemeProvider/brandToCssVars.ts
10321
10304
  var brandToCssVars = (brand, resolvedMode) => {
10322
10305
  const vars = {};
10323
- const colors8 = resolvedMode === "dark" ? brand.colorsDark : brand.colors;
10324
- if (colors8) {
10325
- vars["--color-background"] = colors8.background;
10326
- vars["--color-foreground"] = colors8.foreground;
10327
- vars["--color-muted"] = colors8.muted;
10328
- vars["--color-muted-foreground"] = colors8.mutedForeground;
10329
- vars["--color-border"] = colors8.border;
10330
- vars["--color-primary"] = colors8.primary;
10331
- vars["--color-primary-foreground"] = colors8.primaryForeground;
10332
- vars["--color-destructive"] = colors8.destructive;
10333
- vars["--color-destructive-foreground"] = colors8.destructiveForeground;
10334
- if (colors8.accent !== void 0) vars["--color-accent"] = colors8.accent;
10335
- if (colors8.accentForeground !== void 0)
10336
- vars["--color-accent-foreground"] = colors8.accentForeground;
10306
+ const colors = resolvedMode === "dark" ? brand.colorsDark : brand.colors;
10307
+ if (colors) {
10308
+ vars["--color-background"] = colors.background;
10309
+ vars["--color-foreground"] = colors.foreground;
10310
+ vars["--color-muted"] = colors.muted;
10311
+ vars["--color-muted-foreground"] = colors.mutedForeground;
10312
+ vars["--color-border"] = colors.border;
10313
+ vars["--color-primary"] = colors.primary;
10314
+ vars["--color-primary-foreground"] = colors.primaryForeground;
10315
+ vars["--color-destructive"] = colors.destructive;
10316
+ vars["--color-destructive-foreground"] = colors.destructiveForeground;
10317
+ if (colors.accent !== void 0) vars["--color-accent"] = colors.accent;
10318
+ if (colors.accentForeground !== void 0)
10319
+ vars["--color-accent-foreground"] = colors.accentForeground;
10337
10320
  }
10338
10321
  const sidebar = resolvedMode === "dark" ? brand.sidebarColorsDark : brand.sidebarColors;
10339
10322
  if (sidebar) {
@@ -10711,6 +10694,7 @@ var PageLayout = Object.assign(Root25, {
10711
10694
  // src/blocks/PageHeader/styles.ts
10712
10695
  var titleRowClass = "tw-flex tw-flex-wrap tw-items-center tw-gap-x-3 tw-gap-y-2";
10713
10696
  var titleClass = "tw-m-0 tw-text-3xl tw-font-semibold tw-leading-9 tw-text-foreground tw-break-words";
10697
+ var titleCompactClass = "tw-m-0 tw-text-xl tw-font-semibold tw-leading-7 tw-text-foreground tw-break-words";
10714
10698
  var badgesClass = "tw-flex tw-flex-wrap tw-items-center tw-gap-2 [&_[data-slot=badge]]:tw-rounded-full [&_[data-slot=badge]]:tw-normal-case [&_[data-slot=badge]]:tw-tracking-normal [&_[data-slot=badge]]:tw-py-0";
10715
10699
  var descriptionClass = "tw-m-0 tw-max-w-[800px] tw-break-words tw-text-sm tw-leading-5 tw-text-muted-foreground";
10716
10700
  var PageHeaderDetail = ({
@@ -10722,6 +10706,7 @@ var PageHeaderDetail = ({
10722
10706
  titleIcon,
10723
10707
  badges,
10724
10708
  description,
10709
+ compact = false,
10725
10710
  primaryAction,
10726
10711
  secondaryAction,
10727
10712
  headerNav,
@@ -10735,7 +10720,7 @@ var PageHeaderDetail = ({
10735
10720
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-gap-2 tw-pr-2", children: [
10736
10721
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: titleRowClass, children: [
10737
10722
  titleIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tw-flex tw-shrink-0 tw-items-center", children: titleIcon }),
10738
- /* @__PURE__ */ jsxRuntime.jsx("h1", { className: titleClass, children: title }),
10723
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: compact ? titleCompactClass : titleClass, children: title }),
10739
10724
  badges && /* @__PURE__ */ jsxRuntime.jsx("div", { className: badgesClass, children: badges })
10740
10725
  ] }),
10741
10726
  description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: descriptionClass, children: description })
@@ -14023,423 +14008,6 @@ var DiffView = ({
14023
14008
  }
14024
14009
  );
14025
14010
  };
14026
-
14027
- // src/components/MergeEditor/constants.ts
14028
- var CHUNK_TYPE = {
14029
- UNCHANGED: "unchanged",
14030
- ADDED: "added",
14031
- REMOVED: "removed"
14032
- };
14033
- var CHANGE_CLASS = {
14034
- SAFE: "safe",
14035
- CONFLICT: "conflict"
14036
- };
14037
- var LINE_HEIGHT_PX = 20;
14038
- var PANE_HEADER_HEIGHT_PX = 58;
14039
- var AcceptButton = ({ side, onAccept, argo }) => {
14040
- const label = `Accept ${side === "left" ? "production" : "branch"} version`;
14041
- const Chevron = side === "left" ? icons_exports.ChevronsRight : icons_exports.ChevronsLeft;
14042
- return /* @__PURE__ */ jsxRuntime.jsx(
14043
- Button,
14044
- {
14045
- onClick: onAccept,
14046
- variant: "outline",
14047
- size: "icon-sm",
14048
- title: label,
14049
- "aria-label": label,
14050
- argo,
14051
- children: /* @__PURE__ */ jsxRuntime.jsx(Chevron, { className: "tw-size-5" })
14052
- }
14053
- );
14054
- };
14055
- var AcceptControls = ({
14056
- conflicts,
14057
- side,
14058
- onAccept,
14059
- onDismiss,
14060
- contentRef,
14061
- argo
14062
- }) => /* @__PURE__ */ jsxRuntime.jsx(
14063
- "div",
14064
- {
14065
- className: cn(
14066
- "tw-z-10 tw-flex tw-shrink-0 tw-flex-col tw-items-center",
14067
- conflicts.length > 0 ? "tw-w-7" : "tw-w-0"
14068
- ),
14069
- children: conflicts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
14070
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-shrink-0", style: { height: `${PANE_HEADER_HEIGHT_PX}px` } }),
14071
- /* @__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) => {
14072
- const topLine = side === "left" ? conflict.oldStartLine : conflict.newStartLine;
14073
- const topOffset = (topLine - 1) * LINE_HEIGHT_PX - 2;
14074
- return /* @__PURE__ */ jsxRuntime.jsxs(
14075
- "div",
14076
- {
14077
- className: "tw-absolute tw-inset-x-0 tw-flex tw-flex-col tw-items-center tw-gap-0.5",
14078
- style: { top: `${topOffset}px` },
14079
- children: [
14080
- /* @__PURE__ */ jsxRuntime.jsx(AcceptButton, { side, onAccept: () => onAccept(conflict), argo }),
14081
- onDismiss && /* @__PURE__ */ jsxRuntime.jsx(
14082
- Button,
14083
- {
14084
- onClick: () => onDismiss(conflict),
14085
- variant: "outline",
14086
- size: "icon-sm",
14087
- title: "Dismiss",
14088
- "aria-label": `Dismiss ${side === "left" ? "production" : "branch"} change`,
14089
- argo,
14090
- children: /* @__PURE__ */ jsxRuntime.jsx(icons_exports.X, { className: "tw-size-4" })
14091
- }
14092
- )
14093
- ]
14094
- },
14095
- conflict.id
14096
- );
14097
- }) }) })
14098
- ] })
14099
- }
14100
- );
14101
- var setHighlightedLines = state.StateEffect.define();
14102
- var safeDecoration = view.Decoration.line({ class: "cm-merge-safe-line" });
14103
- var conflictDecoration = view.Decoration.line({ class: "cm-merge-conflict-line" });
14104
- var SafeGutterMarker = class extends view.GutterMarker {
14105
- elementClass = "cm-merge-safe-gutter";
14106
- };
14107
- var ConflictGutterMarker = class extends view.GutterMarker {
14108
- elementClass = "cm-merge-conflict-gutter";
14109
- };
14110
- var safeGutterMarker = new SafeGutterMarker();
14111
- var conflictGutterMarker = new ConflictGutterMarker();
14112
- var createDiffHighlightExtension = () => {
14113
- const field = state.StateField.define({
14114
- create: () => ({ decorations: view.Decoration.none, gutterMarkers: state.RangeSet.empty }),
14115
- update(value, tr) {
14116
- let payload = null;
14117
- for (const effect of tr.effects) {
14118
- if (effect.is(setHighlightedLines)) {
14119
- payload = effect.value;
14120
- }
14121
- }
14122
- if (!payload) {
14123
- return {
14124
- decorations: value.decorations.map(tr.changes),
14125
- gutterMarkers: value.gutterMarkers.map(tr.changes)
14126
- };
14127
- }
14128
- const decoBuilder = new state.RangeSetBuilder();
14129
- const gutterBuilder = new state.RangeSetBuilder();
14130
- const doc = tr.state.doc;
14131
- const { lines, classification } = payload;
14132
- const sorted = [...lines].filter((l) => l >= 1 && l <= doc.lines).sort((a, b) => a - b);
14133
- for (const i of sorted) {
14134
- const cls = classification.get(i);
14135
- if (!cls) continue;
14136
- const isSafe = cls === CHANGE_CLASS.SAFE;
14137
- const line = doc.line(i);
14138
- decoBuilder.add(line.from, line.from, isSafe ? safeDecoration : conflictDecoration);
14139
- gutterBuilder.add(line.from, line.from, isSafe ? safeGutterMarker : conflictGutterMarker);
14140
- }
14141
- return {
14142
- decorations: decoBuilder.finish(),
14143
- gutterMarkers: gutterBuilder.finish()
14144
- };
14145
- },
14146
- provide: (f) => [
14147
- view.EditorView.decorations.from(f, (val) => val.decorations),
14148
- view.gutterLineClass.from(f, (val) => val.gutterMarkers)
14149
- ]
14150
- });
14151
- const theme2 = view.EditorView.theme({
14152
- ".cm-merge-safe-line": {
14153
- backgroundColor: `${colors3__default.default.primary[100]} !important`,
14154
- boxShadow: `inset 3px 0 0 ${colors3__default.default.primary[500]}`
14155
- },
14156
- ".cm-merge-conflict-line": {
14157
- backgroundColor: `${colors3__default.default.warning[100]} !important`,
14158
- boxShadow: `inset 3px 0 0 ${colors3__default.default.warning[500]}`
14159
- },
14160
- ".cm-merge-safe-gutter": {
14161
- backgroundColor: `${colors3__default.default.primary[200]} !important`
14162
- },
14163
- ".cm-merge-conflict-gutter": {
14164
- backgroundColor: `${colors3__default.default.warning[200]} !important`
14165
- }
14166
- });
14167
- return [field, theme2];
14168
- };
14169
- var updateHighlightedLines = (view, lines, classification) => {
14170
- view.dispatch({ effects: setHighlightedLines.of({ lines, classification }) });
14171
- };
14172
- var EMPTY_LINES = /* @__PURE__ */ new Set();
14173
- var EMPTY_CLASSIFICATION = /* @__PURE__ */ new Map();
14174
- var MergePane = ({
14175
- value,
14176
- highlightedLines,
14177
- lineClassification,
14178
- readOnly = false,
14179
- onChange,
14180
- header,
14181
- headerClassName,
14182
- className,
14183
- onScrollDOMReady,
14184
- deleted = false
14185
- }) => {
14186
- const editorRef = react.useRef(null);
14187
- const extensions = react.useMemo(
14188
- () => [
14189
- createDiffHighlightExtension(),
14190
- view.EditorView.theme({
14191
- "&.cm-editor": {
14192
- height: "100%",
14193
- backgroundColor: deleted ? colors3__default.default.error[100] : colors3__default.default.neutral[50],
14194
- outline: "none"
14195
- },
14196
- ".cm-gutters": {
14197
- backgroundColor: deleted ? colors3__default.default.error[200] : colors3__default.default.neutral[100]
14198
- },
14199
- "*": { lineHeight: `${LINE_HEIGHT_PX}px` },
14200
- ".cm-lineNumbers .cm-gutterElement": { padding: "0 0 0 25px" }
14201
- }),
14202
- // Recalc viewport after every doc change so late-settling layouts (alerts
14203
- // appearing above the editor) don't leave trailing lines blank.
14204
- view.EditorView.updateListener.of((update) => {
14205
- if (update.docChanged) {
14206
- requestAnimationFrame(() => update.view.dispatch({}));
14207
- }
14208
- })
14209
- ],
14210
- [deleted]
14211
- );
14212
- react.useEffect(() => {
14213
- const view = editorRef.current?.view;
14214
- if (!view) return;
14215
- updateHighlightedLines(
14216
- view,
14217
- deleted ? EMPTY_LINES : highlightedLines,
14218
- deleted ? EMPTY_CLASSIFICATION : lineClassification
14219
- );
14220
- }, [highlightedLines, lineClassification, deleted]);
14221
- const handleCreateEditor = react.useCallback(
14222
- (view) => {
14223
- updateHighlightedLines(
14224
- view,
14225
- deleted ? EMPTY_LINES : highlightedLines,
14226
- deleted ? EMPTY_CLASSIFICATION : lineClassification
14227
- );
14228
- onScrollDOMReady?.(view.scrollDOM);
14229
- },
14230
- [highlightedLines, lineClassification, onScrollDOMReady, deleted]
14231
- );
14232
- react.useEffect(() => {
14233
- return () => onScrollDOMReady?.(null);
14234
- }, [onScrollDOMReady]);
14235
- react.useEffect(() => {
14236
- const view = editorRef.current?.view;
14237
- const wrapper = view?.dom.parentElement;
14238
- if (!view || !wrapper) return;
14239
- const observer = new ResizeObserver(() => view.dispatch({}));
14240
- observer.observe(wrapper);
14241
- return () => observer.disconnect();
14242
- }, []);
14243
- return /* @__PURE__ */ jsxRuntime.jsxs(
14244
- "div",
14245
- {
14246
- className: cn(
14247
- "tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-overflow-hidden",
14248
- className,
14249
- deleted && "tw-border-error-300"
14250
- ),
14251
- children: [
14252
- header && /* @__PURE__ */ jsxRuntime.jsx(
14253
- "div",
14254
- {
14255
- className: cn(
14256
- "tw-px-4 tw-py-3",
14257
- deleted ? "tw-border-b tw-border-error-200 tw-bg-error-100" : "tw-bg-background",
14258
- headerClassName
14259
- ),
14260
- children: header
14261
- }
14262
- ),
14263
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-flex tw-h-0 tw-flex-1 tw-flex-col [&_>div]:tw-h-full", children: /* @__PURE__ */ jsxRuntime.jsx(
14264
- CodeMirror__default.default,
14265
- {
14266
- ref: editorRef,
14267
- height: "100%",
14268
- value,
14269
- onChange,
14270
- extensions,
14271
- readOnly,
14272
- onCreateEditor: handleCreateEditor,
14273
- basicSetup: { lineNumbers: true, drawSelection: false }
14274
- }
14275
- ) })
14276
- ]
14277
- }
14278
- );
14279
- };
14280
- var useScrollSync = () => {
14281
- const scrollersRef = react.useRef([]);
14282
- const followersRef = react.useRef(/* @__PURE__ */ new Map());
14283
- const isSyncingRef = react.useRef(false);
14284
- const scrollerCallbacksRef = react.useRef(/* @__PURE__ */ new Map());
14285
- const followerCallbacksRef = react.useRef(/* @__PURE__ */ new Map());
14286
- const updateFollowers = react.useCallback(() => {
14287
- for (const [, { paneIndex, el }] of followersRef.current) {
14288
- const scroller = scrollersRef.current[paneIndex];
14289
- if (!scroller) continue;
14290
- el.style.transform = `translateY(-${scroller.scrollTop}px)`;
14291
- }
14292
- }, []);
14293
- const handleScroll = react.useCallback(
14294
- (e) => {
14295
- if (isSyncingRef.current) return;
14296
- isSyncingRef.current = true;
14297
- const sourceScrollTop = e.target.scrollTop;
14298
- for (const scroller of scrollersRef.current) {
14299
- if (!scroller || scroller === e.target) continue;
14300
- const targetMax = Math.max(0, scroller.scrollHeight - scroller.clientHeight);
14301
- scroller.scrollTop = Math.min(sourceScrollTop, targetMax);
14302
- }
14303
- updateFollowers();
14304
- isSyncingRef.current = false;
14305
- },
14306
- [updateFollowers]
14307
- );
14308
- const registerScroller = react.useCallback(
14309
- (index) => {
14310
- const existing = scrollerCallbacksRef.current.get(index);
14311
- if (existing) return existing;
14312
- const callback = (el) => {
14313
- const prev = scrollersRef.current[index];
14314
- if (prev === el) return;
14315
- prev?.removeEventListener("scroll", handleScroll);
14316
- scrollersRef.current[index] = el;
14317
- el?.addEventListener("scroll", handleScroll, { passive: true });
14318
- };
14319
- scrollerCallbacksRef.current.set(index, callback);
14320
- return callback;
14321
- },
14322
- [handleScroll]
14323
- );
14324
- const registerFollower = react.useCallback((paneIndex, key) => {
14325
- const existing = followerCallbacksRef.current.get(key);
14326
- if (existing) return existing;
14327
- const callback = (el) => {
14328
- if (el) {
14329
- followersRef.current.set(key, { paneIndex, el });
14330
- } else {
14331
- followersRef.current.delete(key);
14332
- }
14333
- };
14334
- followerCallbacksRef.current.set(key, callback);
14335
- return callback;
14336
- }, []);
14337
- return { registerScroller, registerFollower };
14338
- };
14339
- var EMPTY_LINES2 = /* @__PURE__ */ new Set();
14340
- var EMPTY_CLASSIFICATION2 = /* @__PURE__ */ new Map();
14341
- var MergeEditor = ({
14342
- mergeValue,
14343
- handleMergeChange,
14344
- leftText,
14345
- rightText,
14346
- leftConflicts,
14347
- rightConflicts,
14348
- leftHighlightedLines,
14349
- rightHighlightedLines,
14350
- leftClassification,
14351
- rightClassification,
14352
- mergeHighlightedLines,
14353
- mergeClassification,
14354
- acceptLeft,
14355
- acceptRight,
14356
- dismissLeft,
14357
- dismissRight,
14358
- leftHeader,
14359
- middleHeader,
14360
- middleHeaderClassName,
14361
- middleClassName,
14362
- rightHeader,
14363
- className,
14364
- argo,
14365
- leftDeleted = false,
14366
- rightDeleted = false
14367
- }) => {
14368
- const { registerScroller, registerFollower } = useScrollSync();
14369
- const anySideDeleted = leftDeleted || rightDeleted;
14370
- return /* @__PURE__ */ jsxRuntime.jsxs(
14371
- "div",
14372
- {
14373
- className: cn(
14374
- "tw-flex tw-h-full tw-min-h-0 tw-overflow-hidden tw-bg-background tw-gap-3",
14375
- className
14376
- ),
14377
- children: [
14378
- /* @__PURE__ */ jsxRuntime.jsx(
14379
- MergePane,
14380
- {
14381
- value: leftText,
14382
- highlightedLines: leftHighlightedLines,
14383
- lineClassification: leftClassification,
14384
- readOnly: true,
14385
- header: leftHeader,
14386
- className: "tw-rounded-r-lg tw-border tw-border-border",
14387
- onScrollDOMReady: registerScroller(0),
14388
- deleted: leftDeleted
14389
- }
14390
- ),
14391
- /* @__PURE__ */ jsxRuntime.jsx(
14392
- AcceptControls,
14393
- {
14394
- conflicts: leftDeleted ? [] : leftConflicts,
14395
- side: "left",
14396
- onAccept: acceptLeft,
14397
- onDismiss: dismissLeft,
14398
- contentRef: registerFollower(0, "left-controls"),
14399
- argo
14400
- }
14401
- ),
14402
- /* @__PURE__ */ jsxRuntime.jsx(
14403
- MergePane,
14404
- {
14405
- value: mergeValue,
14406
- highlightedLines: anySideDeleted ? EMPTY_LINES2 : mergeHighlightedLines,
14407
- lineClassification: anySideDeleted ? EMPTY_CLASSIFICATION2 : mergeClassification,
14408
- onChange: handleMergeChange,
14409
- header: middleHeader,
14410
- headerClassName: middleHeaderClassName,
14411
- className: cn("tw-border tw-border-border tw-rounded-lg", middleClassName),
14412
- onScrollDOMReady: registerScroller(1)
14413
- }
14414
- ),
14415
- /* @__PURE__ */ jsxRuntime.jsx(
14416
- AcceptControls,
14417
- {
14418
- conflicts: rightDeleted ? [] : rightConflicts,
14419
- side: "right",
14420
- onAccept: acceptRight,
14421
- onDismiss: dismissRight,
14422
- contentRef: registerFollower(2, "right-controls"),
14423
- argo
14424
- }
14425
- ),
14426
- /* @__PURE__ */ jsxRuntime.jsx(
14427
- MergePane,
14428
- {
14429
- value: rightText,
14430
- highlightedLines: rightHighlightedLines,
14431
- lineClassification: rightClassification,
14432
- readOnly: true,
14433
- header: rightHeader,
14434
- className: "tw-rounded-l-lg tw-border tw-border-border",
14435
- onScrollDOMReady: registerScroller(2),
14436
- deleted: rightDeleted
14437
- }
14438
- )
14439
- ]
14440
- }
14441
- );
14442
- };
14443
14011
  var PaneHeader = ({ label, sublabel }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
14444
14012
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tw-m-0 tw-text-sm tw-font-medium tw-text-foreground", children: label }),
14445
14013
  sublabel && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "tw-m-0 tw-text-xs tw-text-muted-foreground", children: sublabel })
@@ -14469,6 +14037,17 @@ var ConflictStatusIndicator = ({ remainingConflicts, remainingSafeChanges }) =>
14469
14037
  }
14470
14038
  );
14471
14039
  };
14040
+
14041
+ // src/components/MergeEditor/constants.ts
14042
+ var CHUNK_TYPE = {
14043
+ UNCHANGED: "unchanged",
14044
+ ADDED: "added",
14045
+ REMOVED: "removed"
14046
+ };
14047
+ var CHANGE_CLASS = {
14048
+ SAFE: "safe",
14049
+ CONFLICT: "conflict"
14050
+ };
14472
14051
  var computeDiffChunks = (oldText, newText) => {
14473
14052
  const changes = diff.diffLines(oldText, newText);
14474
14053
  const chunks = [];
@@ -15081,6 +14660,7 @@ var SelectField = ({
15081
14660
  required,
15082
14661
  help,
15083
14662
  className,
14663
+ items,
15084
14664
  options,
15085
14665
  placeholder,
15086
14666
  triggerClassName,
@@ -15090,6 +14670,7 @@ var SelectField = ({
15090
14670
  ...rootProps
15091
14671
  }) => {
15092
14672
  const field = useFieldContext();
14673
+ const resolved = items ?? options ?? [];
15093
14674
  return /* @__PURE__ */ jsxRuntime.jsx(FieldShell, { field, label, required, help, className, children: /* @__PURE__ */ jsxRuntime.jsxs(
15094
14675
  Select.Root,
15095
14676
  {
@@ -15111,7 +14692,7 @@ var SelectField = ({
15111
14692
  onBlur: field.handleBlur
15112
14693
  }
15113
14694
  ),
15114
- /* @__PURE__ */ jsxRuntime.jsx(Select.Content, { variant: variant === "argo" ? "argo" : "default", children: options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(Select.Item, { value: option.value, children: option.label }, option.value)) })
14695
+ /* @__PURE__ */ jsxRuntime.jsx(Select.Content, { variant: variant === "argo" ? "argo" : "default", children: resolved.map((option) => /* @__PURE__ */ jsxRuntime.jsx(Select.Item, { value: option.value, children: option.label }, option.value)) })
15115
14696
  ]
15116
14697
  }
15117
14698
  ) });
@@ -15436,751 +15017,6 @@ var ZoomableSvg = ({ html, copyText, className }) => {
15436
15017
  }
15437
15018
  );
15438
15019
  };
15439
- var ButtonToolbar = ({ value, children }) => {
15440
- if (!value && !children) return null;
15441
- 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: [
15442
- !!value && /* @__PURE__ */ jsxRuntime.jsx(ClipboardButton, { size: "icon-sm", variant: "invisible", text: value }),
15443
- children
15444
- ] });
15445
- };
15446
- var baseThemeStyles = {
15447
- "*": { lineHeight: "20px" },
15448
- "*::selection": {
15449
- backgroundColor: colors3__default.default.secondary[500],
15450
- color: `${colors3__default.default.white} !important`
15451
- },
15452
- '&.cm-editor:has(.cm-content[contenteditable="false"])': { backgroundColor: colors3__default.default.neutral[150] },
15453
- '&.cm-editor:has(.cm-content[contenteditable="false"]) .cm-gutters': {
15454
- backgroundColor: colors3__default.default.neutral[200]
15455
- },
15456
- "&.cm-editor .cm-scroller": { overflowAnchor: "none" },
15457
- "&.cm-editor, &.cm-editor .cm-scroller": {
15458
- minHeight: "100%",
15459
- flexGrow: 1,
15460
- alignItems: "stretch !important",
15461
- outline: "none"
15462
- },
15463
- ".cm-gutter.cm-foldGutter": { display: "none !important" },
15464
- ".cm-gutter.cm-lineNumbers": { paddingLeft: "20px", paddingRight: "6px" },
15465
- ".cm-gutters": { height: "auto" },
15466
- // tokens overrides
15467
- ".cm-line .tok-string": { color: colors3__default.default.warning[700] },
15468
- // merge (diff) view
15469
- '&[class*="cm-merge-"] .cm-deletedLine': { backgroundColor: colors3__default.default.error[100] },
15470
- '&[class*="cm-merge-"] .cm-changedLine': { backgroundColor: colors3__default.default.primary[100] },
15471
- '&[class*="cm-merge-"] .cm-deletedLineGutter': { backgroundColor: colors3__default.default.error[200] },
15472
- '&[class*="cm-merge-"] .cm-changedLineGutter': { backgroundColor: colors3__default.default.primary[200] },
15473
- '&[class*="cm-merge-"] .cm-deletedText': { background: colors3__default.default.error[200] },
15474
- '&[class*="cm-merge-"] .cm-changedText': { background: colors3__default.default.primary[200] },
15475
- '&[class*="cm-merge-"]': {
15476
- backgroundColor: `${colors3__default.default.white} !important`
15477
- },
15478
- '&[class*="cm-merge-"] .cm-gutters': {
15479
- backgroundColor: `${colors3__default.default.white} !important`
15480
- },
15481
- ".cm-changeGutter": { position: "absolute", zIndex: -1, width: "100%", paddingLeft: 0 },
15482
- '&[class*="cm-merge-"] .cm-changedLine,&[class*="cm-merge-"] .cm-line, &[class*="cm-merge-"] .cm-deletedChunk': { paddingLeft: 0 }
15483
- };
15484
- var BASIS_SETUP = { drawSelection: false };
15485
- var customTheme = codemirrorThemeGithub.githubLightInit({
15486
- settings: {
15487
- fontFamily: `'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New'`,
15488
- background: colors3__default.default.neutral[50],
15489
- gutterBackground: colors3__default.default.neutral[100],
15490
- gutterBorder: "transparent",
15491
- lineHighlight: "transparent",
15492
- selection: colors3__default.default.secondary[500]
15493
- }
15494
- });
15495
- var getLanguageMode = (mode) => {
15496
- switch (mode) {
15497
- case "text/x-python":
15498
- return langPython.python();
15499
- case "text/x-sql":
15500
- return langSql.sql({ upperCaseKeywords: true });
15501
- case "text/x-sfsql":
15502
- return language.StreamLanguage.define(codemirrorLangSfsql.sfsql);
15503
- case "text/x-plsql":
15504
- return langSql.sql({ upperCaseKeywords: true, dialect: langSql.PLSQL });
15505
- case "text/x-rsrc":
15506
- return language.StreamLanguage.define(r.r);
15507
- case "text/x-sh":
15508
- return language.StreamLanguage.define(shell.shell);
15509
- case "text/javascript":
15510
- return langJavascript.javascript({ jsx: true });
15511
- case "text/typescript":
15512
- return langJavascript.javascript({ jsx: true, typescript: true });
15513
- default:
15514
- return langJson.json();
15515
- }
15516
- };
15517
- var ToggleComponentHelp = () => /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
15518
- "Use ",
15519
- /* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "Ctrl+/" }),
15520
- " or ",
15521
- /* @__PURE__ */ jsxRuntime.jsx(Kbd, { children: "Command+/" }),
15522
- " to toggle comments."
15523
- ] });
15524
- var emptyArray = [];
15525
- var emptyObject = {};
15526
- var CodeEditor = ({
15527
- value,
15528
- previousValue,
15529
- onChange,
15530
- mode = "application/json",
15531
- placeholder = "",
15532
- readOnly = false,
15533
- autocompletions = emptyArray,
15534
- extraKeys = emptyObject,
15535
- withToggleCommentHint = false,
15536
- withAutofocus = false,
15537
- withLineNumbers = true,
15538
- withLineWrapping = true,
15539
- withCollapseUnchanged = false,
15540
- withCopyButton = true,
15541
- completeAny = false,
15542
- help = null,
15543
- helpPostfix = null,
15544
- renderAdditionalButtons,
15545
- className
15546
- }) => {
15547
- const commonExtensions = react.useMemo(() => {
15548
- return [
15549
- getLanguageMode(mode),
15550
- mode === "application/json" && lint.linter(langJson.jsonParseLinter()),
15551
- withLineWrapping ? view.EditorView.lineWrapping : [],
15552
- CodeMirror.EditorState.languageData.of(() => [
15553
- { autocomplete: completeAny ? autocomplete.completeAnyWord : autocompletions }
15554
- ]),
15555
- view.keymap.of(
15556
- Object.entries(extraKeys).map(([key, run]) => ({
15557
- key,
15558
- run: () => {
15559
- if (typeof run === "string") return run;
15560
- run();
15561
- return true;
15562
- }
15563
- }))
15564
- ),
15565
- autocomplete.autocompletion({ activateOnTyping: completeAny }),
15566
- view.EditorView.theme(baseThemeStyles)
15567
- ].filter(Boolean);
15568
- }, [autocompletions, completeAny, extraKeys, mode, withLineWrapping]);
15569
- const extensions = react.useMemo(() => {
15570
- return [
15571
- ...commonExtensions,
15572
- view.placeholder(placeholder),
15573
- view.EditorView.editable.of(!readOnly),
15574
- CodeMirror.EditorState.readOnly.of(readOnly),
15575
- previousValue ? merge.unifiedMergeView({
15576
- original: previousValue,
15577
- mergeControls: false,
15578
- highlightChanges: false,
15579
- collapseUnchanged: withCollapseUnchanged ? {} : void 0
15580
- }) : []
15581
- ];
15582
- }, [commonExtensions, placeholder, readOnly, previousValue, withCollapseUnchanged]);
15583
- const config = react.useMemo(() => {
15584
- return {
15585
- ...BASIS_SETUP,
15586
- lineNumbers: withLineNumbers
15587
- };
15588
- }, [withLineNumbers]);
15589
- return (
15590
- // oxlint-disable-next-line jsx-a11y/no-static-element-interactions
15591
- /* @__PURE__ */ jsxRuntime.jsxs(
15592
- "div",
15593
- {
15594
- className: cn(
15595
- "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",
15596
- { "tw-mt-5": !!renderAdditionalButtons },
15597
- className
15598
- ),
15599
- onKeyDown: (event) => {
15600
- if (event.key === keyCodes.ESCAPE) {
15601
- event.stopPropagation();
15602
- }
15603
- },
15604
- children: [
15605
- (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) }) }) }),
15606
- /* @__PURE__ */ jsxRuntime.jsx(
15607
- CodeMirror__default.default,
15608
- {
15609
- theme: customTheme,
15610
- value,
15611
- onChange,
15612
- extensions,
15613
- autoFocus: withAutofocus,
15614
- basicSetup: config
15615
- }
15616
- ),
15617
- !readOnly && (withToggleCommentHint || help || helpPostfix) && /* @__PURE__ */ jsxRuntime.jsxs(HelpBlock, { className: "tw-mt-2 tw-flex tw-flex-wrap tw-gap-1", children: [
15618
- help,
15619
- withToggleCommentHint ? /* @__PURE__ */ jsxRuntime.jsx(ToggleComponentHelp, {}) : null,
15620
- helpPostfix
15621
- ] })
15622
- ]
15623
- }
15624
- )
15625
- );
15626
- };
15627
- var activeQueryFirstLine = view.Decoration.line({ class: "cm-active-query cm-active-query-first" });
15628
- var activeQueryMiddleLine = view.Decoration.line({ class: "cm-active-query" });
15629
- var activeQueryLastLine = view.Decoration.line({ class: "cm-active-query cm-active-query-last" });
15630
- var activeQuerySingleLine = view.Decoration.line({
15631
- class: "cm-active-query cm-active-query-first cm-active-query-last"
15632
- });
15633
- var findActiveQueryRange = (doc, cursorPos, boundaries) => {
15634
- if (boundaries.length === 0) return null;
15635
- let match = boundaries[boundaries.length - 1];
15636
- for (const boundary of boundaries) {
15637
- if (cursorPos <= boundary.to) {
15638
- match = boundary;
15639
- break;
15640
- }
15641
- }
15642
- if (!match) return null;
15643
- const queryText = doc.slice(match.from, match.to);
15644
- const leadingWhitespace = queryText.length - queryText.trimStart().length;
15645
- const trailingWhitespace = queryText.length - queryText.trimEnd().length;
15646
- const trimmedStart = match.from + leadingWhitespace;
15647
- const trimmedEnd = match.to - trailingWhitespace;
15648
- if (trimmedStart >= trimmedEnd) return null;
15649
- return { from: trimmedStart, to: trimmedEnd };
15650
- };
15651
- var computeBoundaries = (queries) => {
15652
- const boundaries = [];
15653
- let offset = 0;
15654
- for (const query of queries) {
15655
- boundaries.push({ from: offset, to: offset + query.length });
15656
- offset += query.length;
15657
- }
15658
- return boundaries;
15659
- };
15660
- var mapBoundariesThroughChanges = (boundaries, changes) => {
15661
- const prevLen = changes.length;
15662
- const mapped = [];
15663
- for (const b of boundaries) {
15664
- const from = changes.mapPos(Math.max(0, Math.min(b.from, prevLen)), -1);
15665
- const to = changes.mapPos(Math.max(0, Math.min(b.to, prevLen)), 1);
15666
- if (from < to) mapped.push({ from, to });
15667
- }
15668
- return mapped;
15669
- };
15670
- var buildDecorations = (view$1, range) => {
15671
- const startLine = view$1.state.doc.lineAt(range.from).number;
15672
- const endLine = view$1.state.doc.lineAt(range.to).number;
15673
- const decorations = [];
15674
- for (let lineNum = startLine; lineNum <= endLine; lineNum++) {
15675
- const lineStart = view$1.state.doc.line(lineNum).from;
15676
- if (startLine === endLine) {
15677
- decorations.push(activeQuerySingleLine.range(lineStart));
15678
- } else if (lineNum === startLine) {
15679
- decorations.push(activeQueryFirstLine.range(lineStart));
15680
- } else if (lineNum === endLine) {
15681
- decorations.push(activeQueryLastLine.range(lineStart));
15682
- } else {
15683
- decorations.push(activeQueryMiddleLine.range(lineStart));
15684
- }
15685
- }
15686
- return view.Decoration.set(decorations);
15687
- };
15688
- var activeQueryHighlight = (splitQueries) => {
15689
- return [
15690
- view.ViewPlugin.fromClass(
15691
- class {
15692
- decorations = view.Decoration.none;
15693
- debounceTimer = null;
15694
- seq = 0;
15695
- cachedDoc = "";
15696
- cachedBoundaries = [];
15697
- destroyed = false;
15698
- constructor(view) {
15699
- this.scheduleDocParse(view);
15700
- }
15701
- update(update) {
15702
- if (update.focusChanged && !update.view.hasFocus) {
15703
- this.decorations = view.Decoration.none;
15704
- return;
15705
- }
15706
- if (update.docChanged) {
15707
- if (this.cachedBoundaries.length > 0) {
15708
- this.cachedBoundaries = mapBoundariesThroughChanges(
15709
- this.cachedBoundaries,
15710
- update.changes
15711
- );
15712
- this.cachedDoc = update.state.doc.toString();
15713
- this.updateFromCache(update.view);
15714
- }
15715
- this.scheduleDocParse(update.view);
15716
- } else if (update.selectionSet || update.focusChanged && update.view.hasFocus) {
15717
- this.updateFromCache(update.view);
15718
- }
15719
- }
15720
- destroy() {
15721
- this.destroyed = true;
15722
- if (this.debounceTimer) clearTimeout(this.debounceTimer);
15723
- }
15724
- /**
15725
- * Update decorations using cached query boundaries.
15726
- * Only mutates this.decorations — does NOT call view.dispatch().
15727
- * When called from update() (sync), CodeMirror picks up the new
15728
- * decorations via the accessor. When called from the async
15729
- * scheduleDocParse callback, the caller must dispatch separately.
15730
- */
15731
- updateFromCache(view$1) {
15732
- if (!view$1.hasFocus) {
15733
- this.decorations = view.Decoration.none;
15734
- return;
15735
- }
15736
- const { main } = view$1.state.selection;
15737
- if (main.from !== main.to) {
15738
- this.decorations = view.Decoration.none;
15739
- return;
15740
- }
15741
- const doc = view$1.state.doc.toString();
15742
- if (doc !== this.cachedDoc) return;
15743
- if (this.cachedBoundaries.length === 0) {
15744
- this.decorations = view.Decoration.none;
15745
- return;
15746
- }
15747
- const range = findActiveQueryRange(doc, main.head, this.cachedBoundaries);
15748
- this.decorations = range ? buildDecorations(view$1, range) : view.Decoration.none;
15749
- }
15750
- /** Parse queries async (debounced) and update decorations. */
15751
- scheduleDocParse(view$1) {
15752
- if (this.debounceTimer) clearTimeout(this.debounceTimer);
15753
- this.debounceTimer = setTimeout(async () => {
15754
- const seq = ++this.seq;
15755
- const doc = view$1.state.doc.toString();
15756
- if (!doc.trim()) {
15757
- this.cachedDoc = doc;
15758
- this.cachedBoundaries = [];
15759
- if (this.decorations !== view.Decoration.none) {
15760
- this.decorations = view.Decoration.none;
15761
- if (!this.destroyed) view$1.dispatch();
15762
- }
15763
- return;
15764
- }
15765
- let queries;
15766
- try {
15767
- queries = await splitQueries(doc);
15768
- } catch {
15769
- return;
15770
- }
15771
- if (this.destroyed || seq !== this.seq) return;
15772
- this.cachedDoc = doc;
15773
- this.cachedBoundaries = computeBoundaries(queries);
15774
- this.updateFromCache(view$1);
15775
- if (!this.destroyed) view$1.dispatch();
15776
- }, 100);
15777
- }
15778
- },
15779
- { decorations: (v) => v.decorations }
15780
- ),
15781
- view.EditorView.baseTheme({
15782
- ".cm-active-query": {
15783
- boxShadow: `inset -1px 0 0 0 ${colors3__default.default.secondary[300]}, inset 1px 0 0 0 ${colors3__default.default.secondary[300]}`,
15784
- marginRight: "8px"
15785
- },
15786
- ".cm-active-query-first": {
15787
- boxShadow: `inset -1px 0 0 0 ${colors3__default.default.secondary[300]}, inset 1px 0 0 0 ${colors3__default.default.secondary[300]}, inset 0 1px 0 0 ${colors3__default.default.secondary[300]}`,
15788
- borderRadius: "4px 4px 0 0"
15789
- },
15790
- ".cm-active-query-last": {
15791
- boxShadow: `inset -1px 0 0 0 ${colors3__default.default.secondary[300]}, inset 1px 0 0 0 ${colors3__default.default.secondary[300]}, inset 0 -1px 0 0 ${colors3__default.default.secondary[300]}`,
15792
- borderRadius: "0 0 4px 4px"
15793
- },
15794
- ".cm-active-query-first.cm-active-query-last": {
15795
- boxShadow: `inset 0 0 0 1px ${colors3__default.default.secondary[300]}`,
15796
- borderRadius: "4px"
15797
- }
15798
- })
15799
- ];
15800
- };
15801
-
15802
- // src/components/CodeEditor/highlighting.ts
15803
- var HighlightMarker = class extends view.GutterMarker {
15804
- toDOM() {
15805
- const marker = document.createElement("div");
15806
- marker.className = "cm-highlight-marker";
15807
- return marker;
15808
- }
15809
- };
15810
- var highlightMarker = new HighlightMarker();
15811
- var forEachLineInRange = (doc, from, to, callback) => {
15812
- const results = [];
15813
- const fromLine = Math.max(1, from + 1);
15814
- const toLine = Math.min(doc.lines, to + 1);
15815
- for (let i = fromLine; i <= toLine; i++) {
15816
- const line = doc.line(i);
15817
- results.push(callback(line.from));
15818
- }
15819
- return results;
15820
- };
15821
- var setHighlightedLinesEffect = state.StateEffect.define();
15822
- var highlightedLinesField = state.StateField.define({
15823
- create() {
15824
- return null;
15825
- },
15826
- update(value, transaction) {
15827
- for (const effect of transaction.effects) {
15828
- if (effect.is(setHighlightedLinesEffect)) {
15829
- return effect.value;
15830
- }
15831
- }
15832
- return value;
15833
- }
15834
- });
15835
- var highlightGutter = view.gutter({
15836
- class: "cm-highlight-gutter",
15837
- markers: (view) => {
15838
- const highlightInfo = view.state.field(highlightedLinesField, false);
15839
- if (!highlightInfo) {
15840
- return state.RangeSet.empty;
15841
- }
15842
- const markers = forEachLineInRange(
15843
- view.state.doc,
15844
- highlightInfo.from,
15845
- highlightInfo.to,
15846
- (lineFrom) => highlightMarker.range(lineFrom)
15847
- );
15848
- return state.RangeSet.of(markers);
15849
- }
15850
- });
15851
- var errorLineDecorations = state.StateField.define({
15852
- create() {
15853
- return view.Decoration.none;
15854
- },
15855
- update(decorations, transaction) {
15856
- decorations = decorations.map(transaction.changes);
15857
- for (const effect of transaction.effects) {
15858
- if (!effect.is(setHighlightedLinesEffect)) {
15859
- continue;
15860
- }
15861
- if (!effect.value || !effect.value.error) {
15862
- return view.Decoration.none;
15863
- }
15864
- const decorationArray = forEachLineInRange(
15865
- transaction.state.doc,
15866
- effect.value.error.from,
15867
- effect.value.error.to,
15868
- (lineFrom) => view.Decoration.line({ class: "cm-error-line" }).range(lineFrom)
15869
- );
15870
- return view.Decoration.set(decorationArray);
15871
- }
15872
- return decorations;
15873
- },
15874
- provide: (f) => view.EditorView.decorations.from(f)
15875
- });
15876
- var processingLineDecorations = state.StateField.define({
15877
- create() {
15878
- return view.Decoration.none;
15879
- },
15880
- update(decorations, transaction) {
15881
- decorations = decorations.map(transaction.changes);
15882
- for (const effect of transaction.effects) {
15883
- if (!effect.is(setHighlightedLinesEffect)) {
15884
- continue;
15885
- }
15886
- if (!effect.value || !effect.value.processing) {
15887
- return view.Decoration.none;
15888
- }
15889
- const decorationArray = forEachLineInRange(
15890
- transaction.state.doc,
15891
- effect.value.processing.from,
15892
- effect.value.processing.to,
15893
- (lineFrom) => view.Decoration.line({ class: "cm-processing-line" }).range(lineFrom)
15894
- );
15895
- return view.Decoration.set(decorationArray);
15896
- }
15897
- return decorations;
15898
- },
15899
- provide: (f) => view.EditorView.decorations.from(f)
15900
- });
15901
- var highlightedLinesTheme = view.EditorView.baseTheme({
15902
- ".cm-highlight-gutter": {
15903
- width: "2px",
15904
- marginRight: "2px"
15905
- },
15906
- ".cm-highlight-marker": {
15907
- width: "2px",
15908
- height: "100%",
15909
- backgroundColor: colors3__default.default.secondary[500]
15910
- },
15911
- ".cm-error-line": {
15912
- backgroundColor: `${colors3__default.default.error[100]} !important`
15913
- },
15914
- ".cm-processing-line": {
15915
- backgroundColor: `${colors3__default.default.secondary[100]} !important`
15916
- }
15917
- });
15918
- function highlightingExtension(queryParser) {
15919
- return [
15920
- highlightedLinesField,
15921
- highlightGutter,
15922
- errorLineDecorations,
15923
- processingLineDecorations,
15924
- highlightedLinesTheme,
15925
- ...queryParser ? activeQueryHighlight(queryParser) : []
15926
- ];
15927
- }
15928
- function updateHighlighting(view, lines) {
15929
- view.dispatch({ effects: setHighlightedLinesEffect.of(lines ?? null) });
15930
- }
15931
- var setSearchEffect = state.StateEffect.define();
15932
- function findMatches(doc, query) {
15933
- if (!query) return [];
15934
- const text = doc.toString();
15935
- try {
15936
- const regex = new RegExp(escapeStringRegexp(query), "gi");
15937
- return Array.from(text.matchAll(regex)).map((match, index) => {
15938
- const from = match.index;
15939
- const to = from + match[0].length;
15940
- return { from, to, text: match[0], localIndex: index };
15941
- });
15942
- } catch (e) {
15943
- console.warn("Invalid search regex:", e);
15944
- return [];
15945
- }
15946
- }
15947
- function createDecorations(matches, selectedLocalIndex) {
15948
- const decorations = matches.map((match) => {
15949
- const isSelected = match.localIndex === selectedLocalIndex;
15950
- const decoration = view.Decoration.mark({
15951
- class: isSelected ? "cm-searchMatch-selected" : "cm-searchMatch"
15952
- });
15953
- return decoration.range(match.from, match.to);
15954
- });
15955
- return view.Decoration.set(decorations, true);
15956
- }
15957
- var searchField = state.StateField.define({
15958
- create() {
15959
- return {
15960
- query: "",
15961
- selectedMatchIndex: void 0,
15962
- matches: [],
15963
- decorations: view.Decoration.none
15964
- };
15965
- },
15966
- update(state, tr) {
15967
- let newState = state;
15968
- for (const effect of tr.effects) {
15969
- if (!effect.is(setSearchEffect)) {
15970
- continue;
15971
- }
15972
- const { query, selectedMatchIndex } = effect.value;
15973
- const matches = findMatches(tr.state.doc, query);
15974
- const decorations = createDecorations(matches, selectedMatchIndex);
15975
- newState = {
15976
- query,
15977
- selectedMatchIndex,
15978
- matches,
15979
- decorations
15980
- };
15981
- }
15982
- if (tr.docChanged && newState.query) {
15983
- const matches = findMatches(tr.state.doc, newState.query);
15984
- const decorations = createDecorations(matches, newState.selectedMatchIndex);
15985
- newState = {
15986
- ...newState,
15987
- matches,
15988
- decorations
15989
- };
15990
- }
15991
- return newState;
15992
- },
15993
- provide: (field) => view.EditorView.decorations.from(field, (state) => state.decorations)
15994
- });
15995
- var searchViewPlugin = view.ViewPlugin.fromClass(
15996
- class {
15997
- lastSelectedIndex;
15998
- update(update) {
15999
- const state = update.state.field(searchField);
16000
- if (state.selectedMatchIndex !== void 0 && state.selectedMatchIndex !== this.lastSelectedIndex) {
16001
- const match = state.matches[state.selectedMatchIndex];
16002
- if (match) {
16003
- requestAnimationFrame(() => {
16004
- update.view.dispatch({
16005
- effects: view.EditorView.scrollIntoView(match.from, { y: "center" })
16006
- });
16007
- });
16008
- }
16009
- this.lastSelectedIndex = state.selectedMatchIndex;
16010
- }
16011
- if (state.selectedMatchIndex === void 0) {
16012
- this.lastSelectedIndex = void 0;
16013
- }
16014
- }
16015
- }
16016
- );
16017
- var searchTheme = view.EditorView.baseTheme({
16018
- ".cm-searchMatch": {
16019
- backgroundColor: colors3__default.default.secondary[100]
16020
- },
16021
- ".cm-searchMatch > span": {
16022
- color: `${colors3__default.default.secondary[600]} !important`
16023
- },
16024
- ".cm-searchMatch-selected": {
16025
- backgroundColor: colors3__default.default.secondary[600]
16026
- },
16027
- ".cm-searchMatch-selected > span": {
16028
- color: `${colors3__default.default.white} !important`
16029
- }
16030
- });
16031
- function searchExtension() {
16032
- return [searchField, searchViewPlugin, searchTheme];
16033
- }
16034
- function updateSearch(view, query, selectedMatchIndex) {
16035
- view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });
16036
- }
16037
- var BASIS_SETUP2 = {
16038
- drawSelection: false,
16039
- defaultKeymap: false,
16040
- completionKeymap: false,
16041
- searchKeymap: false
16042
- };
16043
- var CUSTOM_KEYMAP = [
16044
- {
16045
- key: "Escape",
16046
- stopPropagation: true,
16047
- run: (view) => {
16048
- view.contentDOM.blur();
16049
- return true;
16050
- }
16051
- }
16052
- ];
16053
- var theme = {
16054
- ...baseThemeStyles,
16055
- "&.cm-editor": {
16056
- border: "solid 1px transparent",
16057
- background: colors3__default.default.white,
16058
- borderRadius: "8px",
16059
- paddingTop: "8px",
16060
- paddingBottom: "8px"
16061
- },
16062
- '&.cm-editor:has(.cm-content[contenteditable="true"]):hover': {
16063
- borderColor: colors3__default.default.secondary[500]
16064
- },
16065
- '&.cm-editor:has(.cm-content[contenteditable="true"]):focus-within': {
16066
- borderColor: colors3__default.default.secondary[500],
16067
- boxShadow: `0 0 0 4px ${colors3__default.default.secondary[200]}`
16068
- },
16069
- "&.cm-editor .cm-scroller": { overflowAnchor: "none" },
16070
- "&.cm-editor :is(.cm-gutters,.cm-scroller)": { background: colors3__default.default.white },
16071
- '&.cm-editor:has(.cm-content[contenteditable="false"])': { background: colors3__default.default.neutral[100] },
16072
- '&.cm-editor:has(.cm-content[contenteditable="false"]) :is(.cm-scroller,.cm-gutters)': {
16073
- background: colors3__default.default.neutral[100]
16074
- }
16075
- };
16076
- var SqlEditor = ({
16077
- value,
16078
- onChange,
16079
- onSelectionChange,
16080
- onCreateEditor,
16081
- onDestroyEditor,
16082
- onBlurEditor,
16083
- onFocusEditor,
16084
- placeholder = "",
16085
- searchQuery = "",
16086
- searchMatchIndex,
16087
- readOnly = false,
16088
- extraKeys,
16089
- queryParser,
16090
- autoFocus = false,
16091
- lineNumbers = true,
16092
- className,
16093
- schema,
16094
- variables,
16095
- defaultDatabase,
16096
- defaultSchema,
16097
- highlightLines,
16098
- dialect
16099
- }) => {
16100
- const editorRef = react.useRef(null);
16101
- const extensions = react.useMemo(() => {
16102
- const baseKeymap = [...commands.defaultKeymap, ...CUSTOM_KEYMAP];
16103
- return [
16104
- CodeMirror.EditorView.lineWrapping,
16105
- CodeMirror.keymap.of(extraKeys ? [...extraKeys, ...baseKeymap] : baseKeymap),
16106
- ...codemirrorLangSql.installExtensions({ schema, defaultDatabase, defaultSchema, variables, dialect }),
16107
- searchExtension(),
16108
- highlightingExtension(queryParser),
16109
- CodeMirror.EditorView.theme(theme),
16110
- onBlurEditor ? CodeMirror.EditorView.domEventHandlers({ blur: (_, view) => onBlurEditor(view) }) : [],
16111
- onFocusEditor ? CodeMirror.EditorView.domEventHandlers({ focus: (_, view) => onFocusEditor(view) }) : []
16112
- ];
16113
- }, [
16114
- extraKeys,
16115
- queryParser,
16116
- schema,
16117
- defaultDatabase,
16118
- defaultSchema,
16119
- variables,
16120
- dialect,
16121
- onBlurEditor,
16122
- onFocusEditor
16123
- ]);
16124
- const defaultSetup = react.useMemo(() => {
16125
- return { ...BASIS_SETUP2, lineNumbers };
16126
- }, [lineNumbers]);
16127
- react.useEffect(() => {
16128
- if (editorRef.current?.view) {
16129
- updateHighlighting(editorRef.current.view, highlightLines);
16130
- }
16131
- }, [highlightLines]);
16132
- react.useEffect(() => {
16133
- if (editorRef.current?.view) {
16134
- updateSearch(editorRef.current.view, searchQuery, searchMatchIndex);
16135
- }
16136
- }, [searchQuery, searchMatchIndex]);
16137
- react.useEffect(() => {
16138
- if (!onDestroyEditor) return;
16139
- return () => {
16140
- onDestroyEditor();
16141
- };
16142
- }, [onDestroyEditor]);
16143
- const handleOnCreate = react.useCallback(
16144
- (view, state) => {
16145
- onCreateEditor?.(view, state);
16146
- if (highlightLines) {
16147
- updateHighlighting(view, highlightLines);
16148
- }
16149
- if (searchQuery) {
16150
- updateSearch(view, searchQuery, searchMatchIndex);
16151
- }
16152
- },
16153
- [onCreateEditor, highlightLines, searchQuery, searchMatchIndex]
16154
- );
16155
- const handleOnUpdate = react.useCallback(
16156
- (update) => {
16157
- if (update.selectionSet) {
16158
- const { main } = update.state.selection;
16159
- const text = update.state.sliceDoc(main.from, main.to);
16160
- onSelectionChange?.(text);
16161
- }
16162
- },
16163
- [onSelectionChange]
16164
- );
16165
- return /* @__PURE__ */ jsxRuntime.jsx(
16166
- CodeMirror__default.default,
16167
- {
16168
- ref: editorRef,
16169
- theme: customTheme,
16170
- extensions,
16171
- value,
16172
- onChange,
16173
- onUpdate: handleOnUpdate,
16174
- onCreateEditor: handleOnCreate,
16175
- autoFocus,
16176
- placeholder,
16177
- className,
16178
- readOnly,
16179
- editable: !readOnly,
16180
- basicSetup: defaultSetup
16181
- }
16182
- );
16183
- };
16184
15020
 
16185
15021
  Object.defineProperty(exports, "Slot", {
16186
15022
  enumerable: true,
@@ -16246,7 +15082,6 @@ exports.Checkbox = Checkbox;
16246
15082
  exports.Clipboard = Clipboard;
16247
15083
  exports.ClipboardButton = ClipboardButton;
16248
15084
  exports.ClipboardInline = ClipboardInline;
16249
- exports.CodeEditor = CodeEditor;
16250
15085
  exports.Collapse = Collapse;
16251
15086
  exports.Collapsible = Collapsible;
16252
15087
  exports.CollapsiblePanel = CollapsiblePanel;
@@ -16286,7 +15121,6 @@ exports.Kbd = Kbd;
16286
15121
  exports.Label = Label2;
16287
15122
  exports.Link = Link;
16288
15123
  exports.MarkedText = MarkedText;
16289
- exports.MergeEditor = MergeEditor;
16290
15124
  exports.MessageBubble = MessageBubble;
16291
15125
  exports.Modal = Modal;
16292
15126
  exports.MultiActionButtonGroup = MultiActionButtonGroup;
@@ -16327,7 +15161,6 @@ exports.Skeleton = Skeleton;
16327
15161
  exports.SkeletonList = SkeletonList;
16328
15162
  exports.Slider = Slider;
16329
15163
  exports.SplitButton = SplitButton;
16330
- exports.SqlEditor = SqlEditor;
16331
15164
  exports.Stepper = Stepper;
16332
15165
  exports.SuggestedPrompt = SuggestedPrompt;
16333
15166
  exports.Switch = Switch;