@keboola/design 3.2.0 → 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.js CHANGED
@@ -45,27 +45,9 @@ import * as ResizablePrimitive from 'react-resizable-panels';
45
45
  import * as RadixAvatar from '@radix-ui/react-avatar';
46
46
  import * as RadixTabs from '@radix-ui/react-tabs';
47
47
  import { diffLines, diffWords } from 'diff';
48
- import { Decoration, gutter, EditorView, ViewPlugin, GutterMarker, keymap, placeholder, gutterLineClass } from '@codemirror/view';
49
- import CodeMirror, { EditorState, EditorView as EditorView$1, keymap as keymap$1 } from '@uiw/react-codemirror';
50
- import colors3 from '@keboola/tailwind-config/colors';
51
- import { StateEffect, StateField, RangeSet, RangeSetBuilder } from '@codemirror/state';
52
48
  import { diff3Merge } from 'node-diff3';
53
49
  import { createFormHookContexts, createFormHook } from '@tanstack/react-form';
54
50
  import DOMPurify from 'dompurify';
55
- import { completeAnyWord, autocompletion } from '@codemirror/autocomplete';
56
- import { jsonParseLinter, json } from '@codemirror/lang-json';
57
- import { linter } from '@codemirror/lint';
58
- import { unifiedMergeView } from '@codemirror/merge';
59
- import { javascript } from '@codemirror/lang-javascript';
60
- import { python } from '@codemirror/lang-python';
61
- import { sql, PLSQL } from '@codemirror/lang-sql';
62
- import { StreamLanguage } from '@codemirror/language';
63
- import { r } from '@codemirror/legacy-modes/mode/r';
64
- import { shell } from '@codemirror/legacy-modes/mode/shell';
65
- import { githubLightInit } from '@uiw/codemirror-theme-github';
66
- import { sfsql } from '@keboola/codemirror-lang-sfsql';
67
- import { defaultKeymap } from '@codemirror/commands';
68
- import { installExtensions } from '@keboola/codemirror-lang-sql';
69
51
 
70
52
  var __defProp = Object.defineProperty;
71
53
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -136,7 +118,6 @@ var createChangeInputEvent = (input) => {
136
118
  // src/constants/keyCodes.ts
137
119
  var keyCodes = {
138
120
  ENTER: "Enter",
139
- ESCAPE: "Escape",
140
121
  SPACE: " "
141
122
  };
142
123
  var ThemeContext = createContext(null);
@@ -6872,8 +6853,8 @@ var coerceColorPickerValue = (value) => {
6872
6853
  const body = extractHexBody(value);
6873
6854
  if (body === null || !HEX_CHARSET.test(body)) return PICKER_FALLBACK;
6874
6855
  if (body.length === 3 || body.length === 4) {
6875
- const [r2, g, b] = body;
6876
- return `#${r2}${r2}${g}${g}${b}${b}`.toLowerCase();
6856
+ const [r, g, b] = body;
6857
+ return `#${r}${r}${g}${g}${b}${b}`.toLowerCase();
6877
6858
  }
6878
6859
  if (body.length === 6 || body.length === 8) {
6879
6860
  return `#${body.slice(0, 6).toLowerCase()}`;
@@ -9314,7 +9295,11 @@ var AlertRoot = ({
9314
9295
  "has-[[data-slot=alert-icon]]:tw-gap-x-2",
9315
9296
  // fonts
9316
9297
  "tw-text-sm",
9298
+ // Legacy keeps the fixed neutral text; argo uses the semantic foreground
9299
+ // so the alert flips with the brand's light/dark palette (the categorical
9300
+ // variant tint stays — only the text token becomes brand-aware).
9317
9301
  "tw-text-neutral-800",
9302
+ "data-[argo=true]:tw-text-foreground",
9318
9303
  "tw-text-left",
9319
9304
  "tw-p-4",
9320
9305
  // border
@@ -10288,17 +10273,40 @@ var AIGradientsSvg = () => /* @__PURE__ */ jsx("svg", { width: "0", height: "0",
10288
10273
  // src/components/ThemeProvider/brandToCssVars.ts
10289
10274
  var brandToCssVars = (brand, resolvedMode) => {
10290
10275
  const vars = {};
10291
- const colors8 = resolvedMode === "dark" ? brand.colorsDark : brand.colors;
10292
- if (colors8) {
10293
- vars["--color-background"] = colors8.background;
10294
- vars["--color-foreground"] = colors8.foreground;
10295
- vars["--color-muted"] = colors8.muted;
10296
- vars["--color-muted-foreground"] = colors8.mutedForeground;
10297
- vars["--color-border"] = colors8.border;
10298
- vars["--color-primary"] = colors8.primary;
10299
- vars["--color-primary-foreground"] = colors8.primaryForeground;
10300
- vars["--color-destructive"] = colors8.destructive;
10301
- vars["--color-destructive-foreground"] = colors8.destructiveForeground;
10276
+ const colors = resolvedMode === "dark" ? brand.colorsDark : brand.colors;
10277
+ if (colors) {
10278
+ vars["--color-background"] = colors.background;
10279
+ vars["--color-foreground"] = colors.foreground;
10280
+ vars["--color-muted"] = colors.muted;
10281
+ vars["--color-muted-foreground"] = colors.mutedForeground;
10282
+ vars["--color-border"] = colors.border;
10283
+ vars["--color-primary"] = colors.primary;
10284
+ vars["--color-primary-foreground"] = colors.primaryForeground;
10285
+ vars["--color-destructive"] = colors.destructive;
10286
+ vars["--color-destructive-foreground"] = colors.destructiveForeground;
10287
+ if (colors.accent !== void 0) vars["--color-accent"] = colors.accent;
10288
+ if (colors.accentForeground !== void 0)
10289
+ vars["--color-accent-foreground"] = colors.accentForeground;
10290
+ }
10291
+ const sidebar = resolvedMode === "dark" ? brand.sidebarColorsDark : brand.sidebarColors;
10292
+ if (sidebar) {
10293
+ const sidebarVars = {
10294
+ "--color-sidebar": sidebar.sidebar,
10295
+ "--color-sidebar-foreground": sidebar.sidebarForeground,
10296
+ "--color-sidebar-primary": sidebar.sidebarPrimary,
10297
+ "--color-sidebar-primary-foreground": sidebar.sidebarPrimaryForeground,
10298
+ "--color-sidebar-accent": sidebar.sidebarAccent,
10299
+ "--color-sidebar-accent-foreground": sidebar.sidebarAccentForeground,
10300
+ "--color-sidebar-border": sidebar.sidebarBorder,
10301
+ "--color-sidebar-ring": sidebar.sidebarRing
10302
+ };
10303
+ for (const [name, value] of Object.entries(sidebarVars)) {
10304
+ if (value !== void 0) vars[name] = value;
10305
+ }
10306
+ }
10307
+ const fontFamily = brand.typography?.fontFamily?.trim();
10308
+ if (fontFamily) {
10309
+ vars["--font-sans"] = fontFamily;
10302
10310
  }
10303
10311
  if (brand.radii) {
10304
10312
  vars["--radius-sm"] = brand.radii.sm;
@@ -10386,7 +10394,7 @@ var useTheme = () => {
10386
10394
  const context = use(ThemeContext);
10387
10395
  if (context === null) {
10388
10396
  throw new Error(
10389
- "useTheme must be used within a <ThemeProvider>. Wrap your app root with <ThemeProvider brand={...}> from @keboola/design."
10397
+ "useTheme must be used within a <ThemeProvider>. Wrap your app root with <ThemeProvider> from @keboola/design."
10390
10398
  );
10391
10399
  }
10392
10400
  return context;
@@ -10395,7 +10403,7 @@ var useColorScheme = () => {
10395
10403
  const context = use(ThemeContext);
10396
10404
  if (context === null) {
10397
10405
  throw new Error(
10398
- "useColorScheme must be used within a <ThemeProvider>. Wrap your app root with <ThemeProvider colorScheme={...}> from @keboola/design."
10406
+ "useColorScheme must be used within a <ThemeProvider>. Wrap your app root with <ThemeProvider> from @keboola/design."
10399
10407
  );
10400
10408
  }
10401
10409
  return { colorScheme: context.colorScheme, resolvedMode: context.resolvedMode };
@@ -10656,6 +10664,7 @@ var PageLayout = Object.assign(Root25, {
10656
10664
  // src/blocks/PageHeader/styles.ts
10657
10665
  var titleRowClass = "tw-flex tw-flex-wrap tw-items-center tw-gap-x-3 tw-gap-y-2";
10658
10666
  var titleClass = "tw-m-0 tw-text-3xl tw-font-semibold tw-leading-9 tw-text-foreground tw-break-words";
10667
+ var titleCompactClass = "tw-m-0 tw-text-xl tw-font-semibold tw-leading-7 tw-text-foreground tw-break-words";
10659
10668
  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";
10660
10669
  var descriptionClass = "tw-m-0 tw-max-w-[800px] tw-break-words tw-text-sm tw-leading-5 tw-text-muted-foreground";
10661
10670
  var PageHeaderDetail = ({
@@ -10667,6 +10676,7 @@ var PageHeaderDetail = ({
10667
10676
  titleIcon,
10668
10677
  badges,
10669
10678
  description,
10679
+ compact = false,
10670
10680
  primaryAction,
10671
10681
  secondaryAction,
10672
10682
  headerNav,
@@ -10680,7 +10690,7 @@ var PageHeaderDetail = ({
10680
10690
  /* @__PURE__ */ jsxs("div", { className: "tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-gap-2 tw-pr-2", children: [
10681
10691
  /* @__PURE__ */ jsxs("div", { className: titleRowClass, children: [
10682
10692
  titleIcon && /* @__PURE__ */ jsx("span", { className: "tw-flex tw-shrink-0 tw-items-center", children: titleIcon }),
10683
- /* @__PURE__ */ jsx("h1", { className: titleClass, children: title }),
10693
+ /* @__PURE__ */ jsx("h1", { className: compact ? titleCompactClass : titleClass, children: title }),
10684
10694
  badges && /* @__PURE__ */ jsx("div", { className: badgesClass, children: badges })
10685
10695
  ] }),
10686
10696
  description && /* @__PURE__ */ jsx("p", { className: descriptionClass, children: description })
@@ -13968,423 +13978,6 @@ var DiffView = ({
13968
13978
  }
13969
13979
  );
13970
13980
  };
13971
-
13972
- // src/components/MergeEditor/constants.ts
13973
- var CHUNK_TYPE = {
13974
- UNCHANGED: "unchanged",
13975
- ADDED: "added",
13976
- REMOVED: "removed"
13977
- };
13978
- var CHANGE_CLASS = {
13979
- SAFE: "safe",
13980
- CONFLICT: "conflict"
13981
- };
13982
- var LINE_HEIGHT_PX = 20;
13983
- var PANE_HEADER_HEIGHT_PX = 58;
13984
- var AcceptButton = ({ side, onAccept, argo }) => {
13985
- const label = `Accept ${side === "left" ? "production" : "branch"} version`;
13986
- const Chevron = side === "left" ? icons_exports.ChevronsRight : icons_exports.ChevronsLeft;
13987
- return /* @__PURE__ */ jsx(
13988
- Button,
13989
- {
13990
- onClick: onAccept,
13991
- variant: "outline",
13992
- size: "icon-sm",
13993
- title: label,
13994
- "aria-label": label,
13995
- argo,
13996
- children: /* @__PURE__ */ jsx(Chevron, { className: "tw-size-5" })
13997
- }
13998
- );
13999
- };
14000
- var AcceptControls = ({
14001
- conflicts,
14002
- side,
14003
- onAccept,
14004
- onDismiss,
14005
- contentRef,
14006
- argo
14007
- }) => /* @__PURE__ */ jsx(
14008
- "div",
14009
- {
14010
- className: cn(
14011
- "tw-z-10 tw-flex tw-shrink-0 tw-flex-col tw-items-center",
14012
- conflicts.length > 0 ? "tw-w-7" : "tw-w-0"
14013
- ),
14014
- children: conflicts.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
14015
- /* @__PURE__ */ jsx("div", { className: "tw-shrink-0", style: { height: `${PANE_HEADER_HEIGHT_PX}px` } }),
14016
- /* @__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) => {
14017
- const topLine = side === "left" ? conflict.oldStartLine : conflict.newStartLine;
14018
- const topOffset = (topLine - 1) * LINE_HEIGHT_PX - 2;
14019
- return /* @__PURE__ */ jsxs(
14020
- "div",
14021
- {
14022
- className: "tw-absolute tw-inset-x-0 tw-flex tw-flex-col tw-items-center tw-gap-0.5",
14023
- style: { top: `${topOffset}px` },
14024
- children: [
14025
- /* @__PURE__ */ jsx(AcceptButton, { side, onAccept: () => onAccept(conflict), argo }),
14026
- onDismiss && /* @__PURE__ */ jsx(
14027
- Button,
14028
- {
14029
- onClick: () => onDismiss(conflict),
14030
- variant: "outline",
14031
- size: "icon-sm",
14032
- title: "Dismiss",
14033
- "aria-label": `Dismiss ${side === "left" ? "production" : "branch"} change`,
14034
- argo,
14035
- children: /* @__PURE__ */ jsx(icons_exports.X, { className: "tw-size-4" })
14036
- }
14037
- )
14038
- ]
14039
- },
14040
- conflict.id
14041
- );
14042
- }) }) })
14043
- ] })
14044
- }
14045
- );
14046
- var setHighlightedLines = StateEffect.define();
14047
- var safeDecoration = Decoration.line({ class: "cm-merge-safe-line" });
14048
- var conflictDecoration = Decoration.line({ class: "cm-merge-conflict-line" });
14049
- var SafeGutterMarker = class extends GutterMarker {
14050
- elementClass = "cm-merge-safe-gutter";
14051
- };
14052
- var ConflictGutterMarker = class extends GutterMarker {
14053
- elementClass = "cm-merge-conflict-gutter";
14054
- };
14055
- var safeGutterMarker = new SafeGutterMarker();
14056
- var conflictGutterMarker = new ConflictGutterMarker();
14057
- var createDiffHighlightExtension = () => {
14058
- const field = StateField.define({
14059
- create: () => ({ decorations: Decoration.none, gutterMarkers: RangeSet.empty }),
14060
- update(value, tr) {
14061
- let payload = null;
14062
- for (const effect of tr.effects) {
14063
- if (effect.is(setHighlightedLines)) {
14064
- payload = effect.value;
14065
- }
14066
- }
14067
- if (!payload) {
14068
- return {
14069
- decorations: value.decorations.map(tr.changes),
14070
- gutterMarkers: value.gutterMarkers.map(tr.changes)
14071
- };
14072
- }
14073
- const decoBuilder = new RangeSetBuilder();
14074
- const gutterBuilder = new RangeSetBuilder();
14075
- const doc = tr.state.doc;
14076
- const { lines, classification } = payload;
14077
- const sorted = [...lines].filter((l) => l >= 1 && l <= doc.lines).sort((a, b) => a - b);
14078
- for (const i of sorted) {
14079
- const cls = classification.get(i);
14080
- if (!cls) continue;
14081
- const isSafe = cls === CHANGE_CLASS.SAFE;
14082
- const line = doc.line(i);
14083
- decoBuilder.add(line.from, line.from, isSafe ? safeDecoration : conflictDecoration);
14084
- gutterBuilder.add(line.from, line.from, isSafe ? safeGutterMarker : conflictGutterMarker);
14085
- }
14086
- return {
14087
- decorations: decoBuilder.finish(),
14088
- gutterMarkers: gutterBuilder.finish()
14089
- };
14090
- },
14091
- provide: (f) => [
14092
- EditorView.decorations.from(f, (val) => val.decorations),
14093
- gutterLineClass.from(f, (val) => val.gutterMarkers)
14094
- ]
14095
- });
14096
- const theme2 = EditorView.theme({
14097
- ".cm-merge-safe-line": {
14098
- backgroundColor: `${colors3.primary[100]} !important`,
14099
- boxShadow: `inset 3px 0 0 ${colors3.primary[500]}`
14100
- },
14101
- ".cm-merge-conflict-line": {
14102
- backgroundColor: `${colors3.warning[100]} !important`,
14103
- boxShadow: `inset 3px 0 0 ${colors3.warning[500]}`
14104
- },
14105
- ".cm-merge-safe-gutter": {
14106
- backgroundColor: `${colors3.primary[200]} !important`
14107
- },
14108
- ".cm-merge-conflict-gutter": {
14109
- backgroundColor: `${colors3.warning[200]} !important`
14110
- }
14111
- });
14112
- return [field, theme2];
14113
- };
14114
- var updateHighlightedLines = (view, lines, classification) => {
14115
- view.dispatch({ effects: setHighlightedLines.of({ lines, classification }) });
14116
- };
14117
- var EMPTY_LINES = /* @__PURE__ */ new Set();
14118
- var EMPTY_CLASSIFICATION = /* @__PURE__ */ new Map();
14119
- var MergePane = ({
14120
- value,
14121
- highlightedLines,
14122
- lineClassification,
14123
- readOnly = false,
14124
- onChange,
14125
- header,
14126
- headerClassName,
14127
- className,
14128
- onScrollDOMReady,
14129
- deleted = false
14130
- }) => {
14131
- const editorRef = useRef(null);
14132
- const extensions = useMemo(
14133
- () => [
14134
- createDiffHighlightExtension(),
14135
- EditorView.theme({
14136
- "&.cm-editor": {
14137
- height: "100%",
14138
- backgroundColor: deleted ? colors3.error[100] : colors3.neutral[50],
14139
- outline: "none"
14140
- },
14141
- ".cm-gutters": {
14142
- backgroundColor: deleted ? colors3.error[200] : colors3.neutral[100]
14143
- },
14144
- "*": { lineHeight: `${LINE_HEIGHT_PX}px` },
14145
- ".cm-lineNumbers .cm-gutterElement": { padding: "0 0 0 25px" }
14146
- }),
14147
- // Recalc viewport after every doc change so late-settling layouts (alerts
14148
- // appearing above the editor) don't leave trailing lines blank.
14149
- EditorView.updateListener.of((update) => {
14150
- if (update.docChanged) {
14151
- requestAnimationFrame(() => update.view.dispatch({}));
14152
- }
14153
- })
14154
- ],
14155
- [deleted]
14156
- );
14157
- useEffect(() => {
14158
- const view = editorRef.current?.view;
14159
- if (!view) return;
14160
- updateHighlightedLines(
14161
- view,
14162
- deleted ? EMPTY_LINES : highlightedLines,
14163
- deleted ? EMPTY_CLASSIFICATION : lineClassification
14164
- );
14165
- }, [highlightedLines, lineClassification, deleted]);
14166
- const handleCreateEditor = useCallback(
14167
- (view) => {
14168
- updateHighlightedLines(
14169
- view,
14170
- deleted ? EMPTY_LINES : highlightedLines,
14171
- deleted ? EMPTY_CLASSIFICATION : lineClassification
14172
- );
14173
- onScrollDOMReady?.(view.scrollDOM);
14174
- },
14175
- [highlightedLines, lineClassification, onScrollDOMReady, deleted]
14176
- );
14177
- useEffect(() => {
14178
- return () => onScrollDOMReady?.(null);
14179
- }, [onScrollDOMReady]);
14180
- useEffect(() => {
14181
- const view = editorRef.current?.view;
14182
- const wrapper = view?.dom.parentElement;
14183
- if (!view || !wrapper) return;
14184
- const observer = new ResizeObserver(() => view.dispatch({}));
14185
- observer.observe(wrapper);
14186
- return () => observer.disconnect();
14187
- }, []);
14188
- return /* @__PURE__ */ jsxs(
14189
- "div",
14190
- {
14191
- className: cn(
14192
- "tw-flex tw-min-w-0 tw-flex-1 tw-flex-col tw-overflow-hidden",
14193
- className,
14194
- deleted && "tw-border-error-300"
14195
- ),
14196
- children: [
14197
- header && /* @__PURE__ */ jsx(
14198
- "div",
14199
- {
14200
- className: cn(
14201
- "tw-px-4 tw-py-3",
14202
- deleted ? "tw-border-b tw-border-error-200 tw-bg-error-100" : "tw-bg-background",
14203
- headerClassName
14204
- ),
14205
- children: header
14206
- }
14207
- ),
14208
- /* @__PURE__ */ jsx("div", { className: "tw-flex tw-h-0 tw-flex-1 tw-flex-col [&_>div]:tw-h-full", children: /* @__PURE__ */ jsx(
14209
- CodeMirror,
14210
- {
14211
- ref: editorRef,
14212
- height: "100%",
14213
- value,
14214
- onChange,
14215
- extensions,
14216
- readOnly,
14217
- onCreateEditor: handleCreateEditor,
14218
- basicSetup: { lineNumbers: true, drawSelection: false }
14219
- }
14220
- ) })
14221
- ]
14222
- }
14223
- );
14224
- };
14225
- var useScrollSync = () => {
14226
- const scrollersRef = useRef([]);
14227
- const followersRef = useRef(/* @__PURE__ */ new Map());
14228
- const isSyncingRef = useRef(false);
14229
- const scrollerCallbacksRef = useRef(/* @__PURE__ */ new Map());
14230
- const followerCallbacksRef = useRef(/* @__PURE__ */ new Map());
14231
- const updateFollowers = useCallback(() => {
14232
- for (const [, { paneIndex, el }] of followersRef.current) {
14233
- const scroller = scrollersRef.current[paneIndex];
14234
- if (!scroller) continue;
14235
- el.style.transform = `translateY(-${scroller.scrollTop}px)`;
14236
- }
14237
- }, []);
14238
- const handleScroll = useCallback(
14239
- (e) => {
14240
- if (isSyncingRef.current) return;
14241
- isSyncingRef.current = true;
14242
- const sourceScrollTop = e.target.scrollTop;
14243
- for (const scroller of scrollersRef.current) {
14244
- if (!scroller || scroller === e.target) continue;
14245
- const targetMax = Math.max(0, scroller.scrollHeight - scroller.clientHeight);
14246
- scroller.scrollTop = Math.min(sourceScrollTop, targetMax);
14247
- }
14248
- updateFollowers();
14249
- isSyncingRef.current = false;
14250
- },
14251
- [updateFollowers]
14252
- );
14253
- const registerScroller = useCallback(
14254
- (index) => {
14255
- const existing = scrollerCallbacksRef.current.get(index);
14256
- if (existing) return existing;
14257
- const callback = (el) => {
14258
- const prev = scrollersRef.current[index];
14259
- if (prev === el) return;
14260
- prev?.removeEventListener("scroll", handleScroll);
14261
- scrollersRef.current[index] = el;
14262
- el?.addEventListener("scroll", handleScroll, { passive: true });
14263
- };
14264
- scrollerCallbacksRef.current.set(index, callback);
14265
- return callback;
14266
- },
14267
- [handleScroll]
14268
- );
14269
- const registerFollower = useCallback((paneIndex, key) => {
14270
- const existing = followerCallbacksRef.current.get(key);
14271
- if (existing) return existing;
14272
- const callback = (el) => {
14273
- if (el) {
14274
- followersRef.current.set(key, { paneIndex, el });
14275
- } else {
14276
- followersRef.current.delete(key);
14277
- }
14278
- };
14279
- followerCallbacksRef.current.set(key, callback);
14280
- return callback;
14281
- }, []);
14282
- return { registerScroller, registerFollower };
14283
- };
14284
- var EMPTY_LINES2 = /* @__PURE__ */ new Set();
14285
- var EMPTY_CLASSIFICATION2 = /* @__PURE__ */ new Map();
14286
- var MergeEditor = ({
14287
- mergeValue,
14288
- handleMergeChange,
14289
- leftText,
14290
- rightText,
14291
- leftConflicts,
14292
- rightConflicts,
14293
- leftHighlightedLines,
14294
- rightHighlightedLines,
14295
- leftClassification,
14296
- rightClassification,
14297
- mergeHighlightedLines,
14298
- mergeClassification,
14299
- acceptLeft,
14300
- acceptRight,
14301
- dismissLeft,
14302
- dismissRight,
14303
- leftHeader,
14304
- middleHeader,
14305
- middleHeaderClassName,
14306
- middleClassName,
14307
- rightHeader,
14308
- className,
14309
- argo,
14310
- leftDeleted = false,
14311
- rightDeleted = false
14312
- }) => {
14313
- const { registerScroller, registerFollower } = useScrollSync();
14314
- const anySideDeleted = leftDeleted || rightDeleted;
14315
- return /* @__PURE__ */ jsxs(
14316
- "div",
14317
- {
14318
- className: cn(
14319
- "tw-flex tw-h-full tw-min-h-0 tw-overflow-hidden tw-bg-background tw-gap-3",
14320
- className
14321
- ),
14322
- children: [
14323
- /* @__PURE__ */ jsx(
14324
- MergePane,
14325
- {
14326
- value: leftText,
14327
- highlightedLines: leftHighlightedLines,
14328
- lineClassification: leftClassification,
14329
- readOnly: true,
14330
- header: leftHeader,
14331
- className: "tw-rounded-r-lg tw-border tw-border-border",
14332
- onScrollDOMReady: registerScroller(0),
14333
- deleted: leftDeleted
14334
- }
14335
- ),
14336
- /* @__PURE__ */ jsx(
14337
- AcceptControls,
14338
- {
14339
- conflicts: leftDeleted ? [] : leftConflicts,
14340
- side: "left",
14341
- onAccept: acceptLeft,
14342
- onDismiss: dismissLeft,
14343
- contentRef: registerFollower(0, "left-controls"),
14344
- argo
14345
- }
14346
- ),
14347
- /* @__PURE__ */ jsx(
14348
- MergePane,
14349
- {
14350
- value: mergeValue,
14351
- highlightedLines: anySideDeleted ? EMPTY_LINES2 : mergeHighlightedLines,
14352
- lineClassification: anySideDeleted ? EMPTY_CLASSIFICATION2 : mergeClassification,
14353
- onChange: handleMergeChange,
14354
- header: middleHeader,
14355
- headerClassName: middleHeaderClassName,
14356
- className: cn("tw-border tw-border-border tw-rounded-lg", middleClassName),
14357
- onScrollDOMReady: registerScroller(1)
14358
- }
14359
- ),
14360
- /* @__PURE__ */ jsx(
14361
- AcceptControls,
14362
- {
14363
- conflicts: rightDeleted ? [] : rightConflicts,
14364
- side: "right",
14365
- onAccept: acceptRight,
14366
- onDismiss: dismissRight,
14367
- contentRef: registerFollower(2, "right-controls"),
14368
- argo
14369
- }
14370
- ),
14371
- /* @__PURE__ */ jsx(
14372
- MergePane,
14373
- {
14374
- value: rightText,
14375
- highlightedLines: rightHighlightedLines,
14376
- lineClassification: rightClassification,
14377
- readOnly: true,
14378
- header: rightHeader,
14379
- className: "tw-rounded-l-lg tw-border tw-border-border",
14380
- onScrollDOMReady: registerScroller(2),
14381
- deleted: rightDeleted
14382
- }
14383
- )
14384
- ]
14385
- }
14386
- );
14387
- };
14388
13981
  var PaneHeader = ({ label, sublabel }) => /* @__PURE__ */ jsxs("div", { children: [
14389
13982
  /* @__PURE__ */ jsx("p", { className: "tw-m-0 tw-text-sm tw-font-medium tw-text-foreground", children: label }),
14390
13983
  sublabel && /* @__PURE__ */ jsx("p", { className: "tw-m-0 tw-text-xs tw-text-muted-foreground", children: sublabel })
@@ -14414,6 +14007,17 @@ var ConflictStatusIndicator = ({ remainingConflicts, remainingSafeChanges }) =>
14414
14007
  }
14415
14008
  );
14416
14009
  };
14010
+
14011
+ // src/components/MergeEditor/constants.ts
14012
+ var CHUNK_TYPE = {
14013
+ UNCHANGED: "unchanged",
14014
+ ADDED: "added",
14015
+ REMOVED: "removed"
14016
+ };
14017
+ var CHANGE_CLASS = {
14018
+ SAFE: "safe",
14019
+ CONFLICT: "conflict"
14020
+ };
14417
14021
  var computeDiffChunks = (oldText, newText) => {
14418
14022
  const changes = diffLines(oldText, newText);
14419
14023
  const chunks = [];
@@ -15026,6 +14630,7 @@ var SelectField = ({
15026
14630
  required,
15027
14631
  help,
15028
14632
  className,
14633
+ items,
15029
14634
  options,
15030
14635
  placeholder,
15031
14636
  triggerClassName,
@@ -15035,6 +14640,7 @@ var SelectField = ({
15035
14640
  ...rootProps
15036
14641
  }) => {
15037
14642
  const field = useFieldContext();
14643
+ const resolved = items ?? options ?? [];
15038
14644
  return /* @__PURE__ */ jsx(FieldShell, { field, label, required, help, className, children: /* @__PURE__ */ jsxs(
15039
14645
  Select.Root,
15040
14646
  {
@@ -15056,7 +14662,7 @@ var SelectField = ({
15056
14662
  onBlur: field.handleBlur
15057
14663
  }
15058
14664
  ),
15059
- /* @__PURE__ */ jsx(Select.Content, { variant: variant === "argo" ? "argo" : "default", children: options.map((option) => /* @__PURE__ */ jsx(Select.Item, { value: option.value, children: option.label }, option.value)) })
14665
+ /* @__PURE__ */ jsx(Select.Content, { variant: variant === "argo" ? "argo" : "default", children: resolved.map((option) => /* @__PURE__ */ jsx(Select.Item, { value: option.value, children: option.label }, option.value)) })
15060
14666
  ]
15061
14667
  }
15062
14668
  ) });
@@ -15381,752 +14987,7 @@ var ZoomableSvg = ({ html, copyText, className }) => {
15381
14987
  }
15382
14988
  );
15383
14989
  };
15384
- var ButtonToolbar = ({ value, children }) => {
15385
- if (!value && !children) return null;
15386
- 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: [
15387
- !!value && /* @__PURE__ */ jsx(ClipboardButton, { size: "icon-sm", variant: "invisible", text: value }),
15388
- children
15389
- ] });
15390
- };
15391
- var baseThemeStyles = {
15392
- "*": { lineHeight: "20px" },
15393
- "*::selection": {
15394
- backgroundColor: colors3.secondary[500],
15395
- color: `${colors3.white} !important`
15396
- },
15397
- '&.cm-editor:has(.cm-content[contenteditable="false"])': { backgroundColor: colors3.neutral[150] },
15398
- '&.cm-editor:has(.cm-content[contenteditable="false"]) .cm-gutters': {
15399
- backgroundColor: colors3.neutral[200]
15400
- },
15401
- "&.cm-editor .cm-scroller": { overflowAnchor: "none" },
15402
- "&.cm-editor, &.cm-editor .cm-scroller": {
15403
- minHeight: "100%",
15404
- flexGrow: 1,
15405
- alignItems: "stretch !important",
15406
- outline: "none"
15407
- },
15408
- ".cm-gutter.cm-foldGutter": { display: "none !important" },
15409
- ".cm-gutter.cm-lineNumbers": { paddingLeft: "20px", paddingRight: "6px" },
15410
- ".cm-gutters": { height: "auto" },
15411
- // tokens overrides
15412
- ".cm-line .tok-string": { color: colors3.warning[700] },
15413
- // merge (diff) view
15414
- '&[class*="cm-merge-"] .cm-deletedLine': { backgroundColor: colors3.error[100] },
15415
- '&[class*="cm-merge-"] .cm-changedLine': { backgroundColor: colors3.primary[100] },
15416
- '&[class*="cm-merge-"] .cm-deletedLineGutter': { backgroundColor: colors3.error[200] },
15417
- '&[class*="cm-merge-"] .cm-changedLineGutter': { backgroundColor: colors3.primary[200] },
15418
- '&[class*="cm-merge-"] .cm-deletedText': { background: colors3.error[200] },
15419
- '&[class*="cm-merge-"] .cm-changedText': { background: colors3.primary[200] },
15420
- '&[class*="cm-merge-"]': {
15421
- backgroundColor: `${colors3.white} !important`
15422
- },
15423
- '&[class*="cm-merge-"] .cm-gutters': {
15424
- backgroundColor: `${colors3.white} !important`
15425
- },
15426
- ".cm-changeGutter": { position: "absolute", zIndex: -1, width: "100%", paddingLeft: 0 },
15427
- '&[class*="cm-merge-"] .cm-changedLine,&[class*="cm-merge-"] .cm-line, &[class*="cm-merge-"] .cm-deletedChunk': { paddingLeft: 0 }
15428
- };
15429
- var BASIS_SETUP = { drawSelection: false };
15430
- var customTheme = githubLightInit({
15431
- settings: {
15432
- fontFamily: `'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New'`,
15433
- background: colors3.neutral[50],
15434
- gutterBackground: colors3.neutral[100],
15435
- gutterBorder: "transparent",
15436
- lineHighlight: "transparent",
15437
- selection: colors3.secondary[500]
15438
- }
15439
- });
15440
- var getLanguageMode = (mode) => {
15441
- switch (mode) {
15442
- case "text/x-python":
15443
- return python();
15444
- case "text/x-sql":
15445
- return sql({ upperCaseKeywords: true });
15446
- case "text/x-sfsql":
15447
- return StreamLanguage.define(sfsql);
15448
- case "text/x-plsql":
15449
- return sql({ upperCaseKeywords: true, dialect: PLSQL });
15450
- case "text/x-rsrc":
15451
- return StreamLanguage.define(r);
15452
- case "text/x-sh":
15453
- return StreamLanguage.define(shell);
15454
- case "text/javascript":
15455
- return javascript({ jsx: true });
15456
- case "text/typescript":
15457
- return javascript({ jsx: true, typescript: true });
15458
- default:
15459
- return json();
15460
- }
15461
- };
15462
- var ToggleComponentHelp = () => /* @__PURE__ */ jsxs("div", { children: [
15463
- "Use ",
15464
- /* @__PURE__ */ jsx(Kbd, { children: "Ctrl+/" }),
15465
- " or ",
15466
- /* @__PURE__ */ jsx(Kbd, { children: "Command+/" }),
15467
- " to toggle comments."
15468
- ] });
15469
- var emptyArray = [];
15470
- var emptyObject = {};
15471
- var CodeEditor = ({
15472
- value,
15473
- previousValue,
15474
- onChange,
15475
- mode = "application/json",
15476
- placeholder: placeholder$1 = "",
15477
- readOnly = false,
15478
- autocompletions = emptyArray,
15479
- extraKeys = emptyObject,
15480
- withToggleCommentHint = false,
15481
- withAutofocus = false,
15482
- withLineNumbers = true,
15483
- withLineWrapping = true,
15484
- withCollapseUnchanged = false,
15485
- withCopyButton = true,
15486
- completeAny = false,
15487
- help = null,
15488
- helpPostfix = null,
15489
- renderAdditionalButtons,
15490
- className
15491
- }) => {
15492
- const commonExtensions = useMemo(() => {
15493
- return [
15494
- getLanguageMode(mode),
15495
- mode === "application/json" && linter(jsonParseLinter()),
15496
- withLineWrapping ? EditorView.lineWrapping : [],
15497
- EditorState.languageData.of(() => [
15498
- { autocomplete: completeAny ? completeAnyWord : autocompletions }
15499
- ]),
15500
- keymap.of(
15501
- Object.entries(extraKeys).map(([key, run]) => ({
15502
- key,
15503
- run: () => {
15504
- if (typeof run === "string") return run;
15505
- run();
15506
- return true;
15507
- }
15508
- }))
15509
- ),
15510
- autocompletion({ activateOnTyping: completeAny }),
15511
- EditorView.theme(baseThemeStyles)
15512
- ].filter(Boolean);
15513
- }, [autocompletions, completeAny, extraKeys, mode, withLineWrapping]);
15514
- const extensions = useMemo(() => {
15515
- return [
15516
- ...commonExtensions,
15517
- placeholder(placeholder$1),
15518
- EditorView.editable.of(!readOnly),
15519
- EditorState.readOnly.of(readOnly),
15520
- previousValue ? unifiedMergeView({
15521
- original: previousValue,
15522
- mergeControls: false,
15523
- highlightChanges: false,
15524
- collapseUnchanged: withCollapseUnchanged ? {} : void 0
15525
- }) : []
15526
- ];
15527
- }, [commonExtensions, placeholder$1, readOnly, previousValue, withCollapseUnchanged]);
15528
- const config = useMemo(() => {
15529
- return {
15530
- ...BASIS_SETUP,
15531
- lineNumbers: withLineNumbers
15532
- };
15533
- }, [withLineNumbers]);
15534
- return (
15535
- // oxlint-disable-next-line jsx-a11y/no-static-element-interactions
15536
- /* @__PURE__ */ jsxs(
15537
- "div",
15538
- {
15539
- className: cn(
15540
- "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",
15541
- { "tw-mt-5": !!renderAdditionalButtons },
15542
- className
15543
- ),
15544
- onKeyDown: (event) => {
15545
- if (event.key === keyCodes.ESCAPE) {
15546
- event.stopPropagation();
15547
- }
15548
- },
15549
- children: [
15550
- (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) }) }) }),
15551
- /* @__PURE__ */ jsx(
15552
- CodeMirror,
15553
- {
15554
- theme: customTheme,
15555
- value,
15556
- onChange,
15557
- extensions,
15558
- autoFocus: withAutofocus,
15559
- basicSetup: config
15560
- }
15561
- ),
15562
- !readOnly && (withToggleCommentHint || help || helpPostfix) && /* @__PURE__ */ jsxs(HelpBlock, { className: "tw-mt-2 tw-flex tw-flex-wrap tw-gap-1", children: [
15563
- help,
15564
- withToggleCommentHint ? /* @__PURE__ */ jsx(ToggleComponentHelp, {}) : null,
15565
- helpPostfix
15566
- ] })
15567
- ]
15568
- }
15569
- )
15570
- );
15571
- };
15572
- var activeQueryFirstLine = Decoration.line({ class: "cm-active-query cm-active-query-first" });
15573
- var activeQueryMiddleLine = Decoration.line({ class: "cm-active-query" });
15574
- var activeQueryLastLine = Decoration.line({ class: "cm-active-query cm-active-query-last" });
15575
- var activeQuerySingleLine = Decoration.line({
15576
- class: "cm-active-query cm-active-query-first cm-active-query-last"
15577
- });
15578
- var findActiveQueryRange = (doc, cursorPos, boundaries) => {
15579
- if (boundaries.length === 0) return null;
15580
- let match = boundaries[boundaries.length - 1];
15581
- for (const boundary of boundaries) {
15582
- if (cursorPos <= boundary.to) {
15583
- match = boundary;
15584
- break;
15585
- }
15586
- }
15587
- if (!match) return null;
15588
- const queryText = doc.slice(match.from, match.to);
15589
- const leadingWhitespace = queryText.length - queryText.trimStart().length;
15590
- const trailingWhitespace = queryText.length - queryText.trimEnd().length;
15591
- const trimmedStart = match.from + leadingWhitespace;
15592
- const trimmedEnd = match.to - trailingWhitespace;
15593
- if (trimmedStart >= trimmedEnd) return null;
15594
- return { from: trimmedStart, to: trimmedEnd };
15595
- };
15596
- var computeBoundaries = (queries) => {
15597
- const boundaries = [];
15598
- let offset = 0;
15599
- for (const query of queries) {
15600
- boundaries.push({ from: offset, to: offset + query.length });
15601
- offset += query.length;
15602
- }
15603
- return boundaries;
15604
- };
15605
- var mapBoundariesThroughChanges = (boundaries, changes) => {
15606
- const prevLen = changes.length;
15607
- const mapped = [];
15608
- for (const b of boundaries) {
15609
- const from = changes.mapPos(Math.max(0, Math.min(b.from, prevLen)), -1);
15610
- const to = changes.mapPos(Math.max(0, Math.min(b.to, prevLen)), 1);
15611
- if (from < to) mapped.push({ from, to });
15612
- }
15613
- return mapped;
15614
- };
15615
- var buildDecorations = (view, range) => {
15616
- const startLine = view.state.doc.lineAt(range.from).number;
15617
- const endLine = view.state.doc.lineAt(range.to).number;
15618
- const decorations = [];
15619
- for (let lineNum = startLine; lineNum <= endLine; lineNum++) {
15620
- const lineStart = view.state.doc.line(lineNum).from;
15621
- if (startLine === endLine) {
15622
- decorations.push(activeQuerySingleLine.range(lineStart));
15623
- } else if (lineNum === startLine) {
15624
- decorations.push(activeQueryFirstLine.range(lineStart));
15625
- } else if (lineNum === endLine) {
15626
- decorations.push(activeQueryLastLine.range(lineStart));
15627
- } else {
15628
- decorations.push(activeQueryMiddleLine.range(lineStart));
15629
- }
15630
- }
15631
- return Decoration.set(decorations);
15632
- };
15633
- var activeQueryHighlight = (splitQueries) => {
15634
- return [
15635
- ViewPlugin.fromClass(
15636
- class {
15637
- decorations = Decoration.none;
15638
- debounceTimer = null;
15639
- seq = 0;
15640
- cachedDoc = "";
15641
- cachedBoundaries = [];
15642
- destroyed = false;
15643
- constructor(view) {
15644
- this.scheduleDocParse(view);
15645
- }
15646
- update(update) {
15647
- if (update.focusChanged && !update.view.hasFocus) {
15648
- this.decorations = Decoration.none;
15649
- return;
15650
- }
15651
- if (update.docChanged) {
15652
- if (this.cachedBoundaries.length > 0) {
15653
- this.cachedBoundaries = mapBoundariesThroughChanges(
15654
- this.cachedBoundaries,
15655
- update.changes
15656
- );
15657
- this.cachedDoc = update.state.doc.toString();
15658
- this.updateFromCache(update.view);
15659
- }
15660
- this.scheduleDocParse(update.view);
15661
- } else if (update.selectionSet || update.focusChanged && update.view.hasFocus) {
15662
- this.updateFromCache(update.view);
15663
- }
15664
- }
15665
- destroy() {
15666
- this.destroyed = true;
15667
- if (this.debounceTimer) clearTimeout(this.debounceTimer);
15668
- }
15669
- /**
15670
- * Update decorations using cached query boundaries.
15671
- * Only mutates this.decorations — does NOT call view.dispatch().
15672
- * When called from update() (sync), CodeMirror picks up the new
15673
- * decorations via the accessor. When called from the async
15674
- * scheduleDocParse callback, the caller must dispatch separately.
15675
- */
15676
- updateFromCache(view) {
15677
- if (!view.hasFocus) {
15678
- this.decorations = Decoration.none;
15679
- return;
15680
- }
15681
- const { main } = view.state.selection;
15682
- if (main.from !== main.to) {
15683
- this.decorations = Decoration.none;
15684
- return;
15685
- }
15686
- const doc = view.state.doc.toString();
15687
- if (doc !== this.cachedDoc) return;
15688
- if (this.cachedBoundaries.length === 0) {
15689
- this.decorations = Decoration.none;
15690
- return;
15691
- }
15692
- const range = findActiveQueryRange(doc, main.head, this.cachedBoundaries);
15693
- this.decorations = range ? buildDecorations(view, range) : Decoration.none;
15694
- }
15695
- /** Parse queries async (debounced) and update decorations. */
15696
- scheduleDocParse(view) {
15697
- if (this.debounceTimer) clearTimeout(this.debounceTimer);
15698
- this.debounceTimer = setTimeout(async () => {
15699
- const seq = ++this.seq;
15700
- const doc = view.state.doc.toString();
15701
- if (!doc.trim()) {
15702
- this.cachedDoc = doc;
15703
- this.cachedBoundaries = [];
15704
- if (this.decorations !== Decoration.none) {
15705
- this.decorations = Decoration.none;
15706
- if (!this.destroyed) view.dispatch();
15707
- }
15708
- return;
15709
- }
15710
- let queries;
15711
- try {
15712
- queries = await splitQueries(doc);
15713
- } catch {
15714
- return;
15715
- }
15716
- if (this.destroyed || seq !== this.seq) return;
15717
- this.cachedDoc = doc;
15718
- this.cachedBoundaries = computeBoundaries(queries);
15719
- this.updateFromCache(view);
15720
- if (!this.destroyed) view.dispatch();
15721
- }, 100);
15722
- }
15723
- },
15724
- { decorations: (v) => v.decorations }
15725
- ),
15726
- EditorView.baseTheme({
15727
- ".cm-active-query": {
15728
- boxShadow: `inset -1px 0 0 0 ${colors3.secondary[300]}, inset 1px 0 0 0 ${colors3.secondary[300]}`,
15729
- marginRight: "8px"
15730
- },
15731
- ".cm-active-query-first": {
15732
- boxShadow: `inset -1px 0 0 0 ${colors3.secondary[300]}, inset 1px 0 0 0 ${colors3.secondary[300]}, inset 0 1px 0 0 ${colors3.secondary[300]}`,
15733
- borderRadius: "4px 4px 0 0"
15734
- },
15735
- ".cm-active-query-last": {
15736
- boxShadow: `inset -1px 0 0 0 ${colors3.secondary[300]}, inset 1px 0 0 0 ${colors3.secondary[300]}, inset 0 -1px 0 0 ${colors3.secondary[300]}`,
15737
- borderRadius: "0 0 4px 4px"
15738
- },
15739
- ".cm-active-query-first.cm-active-query-last": {
15740
- boxShadow: `inset 0 0 0 1px ${colors3.secondary[300]}`,
15741
- borderRadius: "4px"
15742
- }
15743
- })
15744
- ];
15745
- };
15746
-
15747
- // src/components/CodeEditor/highlighting.ts
15748
- var HighlightMarker = class extends GutterMarker {
15749
- toDOM() {
15750
- const marker = document.createElement("div");
15751
- marker.className = "cm-highlight-marker";
15752
- return marker;
15753
- }
15754
- };
15755
- var highlightMarker = new HighlightMarker();
15756
- var forEachLineInRange = (doc, from, to, callback) => {
15757
- const results = [];
15758
- const fromLine = Math.max(1, from + 1);
15759
- const toLine = Math.min(doc.lines, to + 1);
15760
- for (let i = fromLine; i <= toLine; i++) {
15761
- const line = doc.line(i);
15762
- results.push(callback(line.from));
15763
- }
15764
- return results;
15765
- };
15766
- var setHighlightedLinesEffect = StateEffect.define();
15767
- var highlightedLinesField = StateField.define({
15768
- create() {
15769
- return null;
15770
- },
15771
- update(value, transaction) {
15772
- for (const effect of transaction.effects) {
15773
- if (effect.is(setHighlightedLinesEffect)) {
15774
- return effect.value;
15775
- }
15776
- }
15777
- return value;
15778
- }
15779
- });
15780
- var highlightGutter = gutter({
15781
- class: "cm-highlight-gutter",
15782
- markers: (view) => {
15783
- const highlightInfo = view.state.field(highlightedLinesField, false);
15784
- if (!highlightInfo) {
15785
- return RangeSet.empty;
15786
- }
15787
- const markers = forEachLineInRange(
15788
- view.state.doc,
15789
- highlightInfo.from,
15790
- highlightInfo.to,
15791
- (lineFrom) => highlightMarker.range(lineFrom)
15792
- );
15793
- return RangeSet.of(markers);
15794
- }
15795
- });
15796
- var errorLineDecorations = StateField.define({
15797
- create() {
15798
- return Decoration.none;
15799
- },
15800
- update(decorations, transaction) {
15801
- decorations = decorations.map(transaction.changes);
15802
- for (const effect of transaction.effects) {
15803
- if (!effect.is(setHighlightedLinesEffect)) {
15804
- continue;
15805
- }
15806
- if (!effect.value || !effect.value.error) {
15807
- return Decoration.none;
15808
- }
15809
- const decorationArray = forEachLineInRange(
15810
- transaction.state.doc,
15811
- effect.value.error.from,
15812
- effect.value.error.to,
15813
- (lineFrom) => Decoration.line({ class: "cm-error-line" }).range(lineFrom)
15814
- );
15815
- return Decoration.set(decorationArray);
15816
- }
15817
- return decorations;
15818
- },
15819
- provide: (f) => EditorView.decorations.from(f)
15820
- });
15821
- var processingLineDecorations = StateField.define({
15822
- create() {
15823
- return Decoration.none;
15824
- },
15825
- update(decorations, transaction) {
15826
- decorations = decorations.map(transaction.changes);
15827
- for (const effect of transaction.effects) {
15828
- if (!effect.is(setHighlightedLinesEffect)) {
15829
- continue;
15830
- }
15831
- if (!effect.value || !effect.value.processing) {
15832
- return Decoration.none;
15833
- }
15834
- const decorationArray = forEachLineInRange(
15835
- transaction.state.doc,
15836
- effect.value.processing.from,
15837
- effect.value.processing.to,
15838
- (lineFrom) => Decoration.line({ class: "cm-processing-line" }).range(lineFrom)
15839
- );
15840
- return Decoration.set(decorationArray);
15841
- }
15842
- return decorations;
15843
- },
15844
- provide: (f) => EditorView.decorations.from(f)
15845
- });
15846
- var highlightedLinesTheme = EditorView.baseTheme({
15847
- ".cm-highlight-gutter": {
15848
- width: "2px",
15849
- marginRight: "2px"
15850
- },
15851
- ".cm-highlight-marker": {
15852
- width: "2px",
15853
- height: "100%",
15854
- backgroundColor: colors3.secondary[500]
15855
- },
15856
- ".cm-error-line": {
15857
- backgroundColor: `${colors3.error[100]} !important`
15858
- },
15859
- ".cm-processing-line": {
15860
- backgroundColor: `${colors3.secondary[100]} !important`
15861
- }
15862
- });
15863
- function highlightingExtension(queryParser) {
15864
- return [
15865
- highlightedLinesField,
15866
- highlightGutter,
15867
- errorLineDecorations,
15868
- processingLineDecorations,
15869
- highlightedLinesTheme,
15870
- ...queryParser ? activeQueryHighlight(queryParser) : []
15871
- ];
15872
- }
15873
- function updateHighlighting(view, lines) {
15874
- view.dispatch({ effects: setHighlightedLinesEffect.of(lines ?? null) });
15875
- }
15876
- var setSearchEffect = StateEffect.define();
15877
- function findMatches(doc, query) {
15878
- if (!query) return [];
15879
- const text = doc.toString();
15880
- try {
15881
- const regex = new RegExp(escapeStringRegexp(query), "gi");
15882
- return Array.from(text.matchAll(regex)).map((match, index) => {
15883
- const from = match.index;
15884
- const to = from + match[0].length;
15885
- return { from, to, text: match[0], localIndex: index };
15886
- });
15887
- } catch (e) {
15888
- console.warn("Invalid search regex:", e);
15889
- return [];
15890
- }
15891
- }
15892
- function createDecorations(matches, selectedLocalIndex) {
15893
- const decorations = matches.map((match) => {
15894
- const isSelected = match.localIndex === selectedLocalIndex;
15895
- const decoration = Decoration.mark({
15896
- class: isSelected ? "cm-searchMatch-selected" : "cm-searchMatch"
15897
- });
15898
- return decoration.range(match.from, match.to);
15899
- });
15900
- return Decoration.set(decorations, true);
15901
- }
15902
- var searchField = StateField.define({
15903
- create() {
15904
- return {
15905
- query: "",
15906
- selectedMatchIndex: void 0,
15907
- matches: [],
15908
- decorations: Decoration.none
15909
- };
15910
- },
15911
- update(state, tr) {
15912
- let newState = state;
15913
- for (const effect of tr.effects) {
15914
- if (!effect.is(setSearchEffect)) {
15915
- continue;
15916
- }
15917
- const { query, selectedMatchIndex } = effect.value;
15918
- const matches = findMatches(tr.state.doc, query);
15919
- const decorations = createDecorations(matches, selectedMatchIndex);
15920
- newState = {
15921
- query,
15922
- selectedMatchIndex,
15923
- matches,
15924
- decorations
15925
- };
15926
- }
15927
- if (tr.docChanged && newState.query) {
15928
- const matches = findMatches(tr.state.doc, newState.query);
15929
- const decorations = createDecorations(matches, newState.selectedMatchIndex);
15930
- newState = {
15931
- ...newState,
15932
- matches,
15933
- decorations
15934
- };
15935
- }
15936
- return newState;
15937
- },
15938
- provide: (field) => EditorView.decorations.from(field, (state) => state.decorations)
15939
- });
15940
- var searchViewPlugin = ViewPlugin.fromClass(
15941
- class {
15942
- lastSelectedIndex;
15943
- update(update) {
15944
- const state = update.state.field(searchField);
15945
- if (state.selectedMatchIndex !== void 0 && state.selectedMatchIndex !== this.lastSelectedIndex) {
15946
- const match = state.matches[state.selectedMatchIndex];
15947
- if (match) {
15948
- requestAnimationFrame(() => {
15949
- update.view.dispatch({
15950
- effects: EditorView.scrollIntoView(match.from, { y: "center" })
15951
- });
15952
- });
15953
- }
15954
- this.lastSelectedIndex = state.selectedMatchIndex;
15955
- }
15956
- if (state.selectedMatchIndex === void 0) {
15957
- this.lastSelectedIndex = void 0;
15958
- }
15959
- }
15960
- }
15961
- );
15962
- var searchTheme = EditorView.baseTheme({
15963
- ".cm-searchMatch": {
15964
- backgroundColor: colors3.secondary[100]
15965
- },
15966
- ".cm-searchMatch > span": {
15967
- color: `${colors3.secondary[600]} !important`
15968
- },
15969
- ".cm-searchMatch-selected": {
15970
- backgroundColor: colors3.secondary[600]
15971
- },
15972
- ".cm-searchMatch-selected > span": {
15973
- color: `${colors3.white} !important`
15974
- }
15975
- });
15976
- function searchExtension() {
15977
- return [searchField, searchViewPlugin, searchTheme];
15978
- }
15979
- function updateSearch(view, query, selectedMatchIndex) {
15980
- view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });
15981
- }
15982
- var BASIS_SETUP2 = {
15983
- drawSelection: false,
15984
- defaultKeymap: false,
15985
- completionKeymap: false,
15986
- searchKeymap: false
15987
- };
15988
- var CUSTOM_KEYMAP = [
15989
- {
15990
- key: "Escape",
15991
- stopPropagation: true,
15992
- run: (view) => {
15993
- view.contentDOM.blur();
15994
- return true;
15995
- }
15996
- }
15997
- ];
15998
- var theme = {
15999
- ...baseThemeStyles,
16000
- "&.cm-editor": {
16001
- border: "solid 1px transparent",
16002
- background: colors3.white,
16003
- borderRadius: "8px",
16004
- paddingTop: "8px",
16005
- paddingBottom: "8px"
16006
- },
16007
- '&.cm-editor:has(.cm-content[contenteditable="true"]):hover': {
16008
- borderColor: colors3.secondary[500]
16009
- },
16010
- '&.cm-editor:has(.cm-content[contenteditable="true"]):focus-within': {
16011
- borderColor: colors3.secondary[500],
16012
- boxShadow: `0 0 0 4px ${colors3.secondary[200]}`
16013
- },
16014
- "&.cm-editor .cm-scroller": { overflowAnchor: "none" },
16015
- "&.cm-editor :is(.cm-gutters,.cm-scroller)": { background: colors3.white },
16016
- '&.cm-editor:has(.cm-content[contenteditable="false"])': { background: colors3.neutral[100] },
16017
- '&.cm-editor:has(.cm-content[contenteditable="false"]) :is(.cm-scroller,.cm-gutters)': {
16018
- background: colors3.neutral[100]
16019
- }
16020
- };
16021
- var SqlEditor = ({
16022
- value,
16023
- onChange,
16024
- onSelectionChange,
16025
- onCreateEditor,
16026
- onDestroyEditor,
16027
- onBlurEditor,
16028
- onFocusEditor,
16029
- placeholder = "",
16030
- searchQuery = "",
16031
- searchMatchIndex,
16032
- readOnly = false,
16033
- extraKeys,
16034
- queryParser,
16035
- autoFocus = false,
16036
- lineNumbers = true,
16037
- className,
16038
- schema,
16039
- variables,
16040
- defaultDatabase,
16041
- defaultSchema,
16042
- highlightLines,
16043
- dialect
16044
- }) => {
16045
- const editorRef = useRef(null);
16046
- const extensions = useMemo(() => {
16047
- const baseKeymap = [...defaultKeymap, ...CUSTOM_KEYMAP];
16048
- return [
16049
- EditorView$1.lineWrapping,
16050
- keymap$1.of(extraKeys ? [...extraKeys, ...baseKeymap] : baseKeymap),
16051
- ...installExtensions({ schema, defaultDatabase, defaultSchema, variables, dialect }),
16052
- searchExtension(),
16053
- highlightingExtension(queryParser),
16054
- EditorView$1.theme(theme),
16055
- onBlurEditor ? EditorView$1.domEventHandlers({ blur: (_, view) => onBlurEditor(view) }) : [],
16056
- onFocusEditor ? EditorView$1.domEventHandlers({ focus: (_, view) => onFocusEditor(view) }) : []
16057
- ];
16058
- }, [
16059
- extraKeys,
16060
- queryParser,
16061
- schema,
16062
- defaultDatabase,
16063
- defaultSchema,
16064
- variables,
16065
- dialect,
16066
- onBlurEditor,
16067
- onFocusEditor
16068
- ]);
16069
- const defaultSetup = useMemo(() => {
16070
- return { ...BASIS_SETUP2, lineNumbers };
16071
- }, [lineNumbers]);
16072
- useEffect(() => {
16073
- if (editorRef.current?.view) {
16074
- updateHighlighting(editorRef.current.view, highlightLines);
16075
- }
16076
- }, [highlightLines]);
16077
- useEffect(() => {
16078
- if (editorRef.current?.view) {
16079
- updateSearch(editorRef.current.view, searchQuery, searchMatchIndex);
16080
- }
16081
- }, [searchQuery, searchMatchIndex]);
16082
- useEffect(() => {
16083
- if (!onDestroyEditor) return;
16084
- return () => {
16085
- onDestroyEditor();
16086
- };
16087
- }, [onDestroyEditor]);
16088
- const handleOnCreate = useCallback(
16089
- (view, state) => {
16090
- onCreateEditor?.(view, state);
16091
- if (highlightLines) {
16092
- updateHighlighting(view, highlightLines);
16093
- }
16094
- if (searchQuery) {
16095
- updateSearch(view, searchQuery, searchMatchIndex);
16096
- }
16097
- },
16098
- [onCreateEditor, highlightLines, searchQuery, searchMatchIndex]
16099
- );
16100
- const handleOnUpdate = useCallback(
16101
- (update) => {
16102
- if (update.selectionSet) {
16103
- const { main } = update.state.selection;
16104
- const text = update.state.sliceDoc(main.from, main.to);
16105
- onSelectionChange?.(text);
16106
- }
16107
- },
16108
- [onSelectionChange]
16109
- );
16110
- return /* @__PURE__ */ jsx(
16111
- CodeMirror,
16112
- {
16113
- ref: editorRef,
16114
- theme: customTheme,
16115
- extensions,
16116
- value,
16117
- onChange,
16118
- onUpdate: handleOnUpdate,
16119
- onCreateEditor: handleOnCreate,
16120
- autoFocus,
16121
- placeholder,
16122
- className,
16123
- readOnly,
16124
- editable: !readOnly,
16125
- basicSetup: defaultSetup
16126
- }
16127
- );
16128
- };
16129
14990
 
16130
- export { Alert, AnswerSummary, AppShell, AutoSaveTextarea, Avatar, Badge, Breadcrumb, Button, ButtonGroup, ButtonInline, Calendar, Card, Checkbox, Clipboard, ClipboardButton, ClipboardInline, CodeEditor, Collapse, Collapsible, CollapsiblePanel, CollapsibleStepHeader, ColorInput, Combobox, Command, CommandGroup, CommandInput, CommandItem, CommandList, ConflictStatusIndicator, DateInput, DatePicker, DateRangeInput, DateRangePicker, DiffType, DiffView, DotsLoader, DropdownMenu, EmptyConfigurationActionCard, EmptySearchContent, EmptyState, ErrorState, FileUpload, FormGroup, FullScreenModal, FullScreenModalBody, FullScreenModalHeader, HelpBlock, HoverCard, InlineStepDetail, InlineStepLabel, InputGroup, InputOtp, Kbd, Label2 as Label, Link, MarkedText, MergeEditor, MessageBubble, Modal, MultiActionButtonGroup, MultiCombobox, Navbar, NumberInput, PageHeader, PageLayout, PageToolbar, Pagination, PaneHeader, PanelWithDetails, PasswordInput, PlanApproval, PlanRewritingIndicator, Popconfirm, Popover, Progress, PromptInput, Question, QuestionBlock, RadioGroup2 as RadioGroup, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Search, SearchForm, SearchInput, SearchInputWithNavigation, Select, Separator2 as Separator, Sheet, Sidebar, SidebarProvider, Skeleton, SkeletonList, Slider, SplitButton, SqlEditor, Stepper, SuggestedPrompt, Switch, Table, Tabs2 as Tabs, TabsContent, Tagger, TextInput, Textarea, ThemeDecorator, ThemeProvider, ThinkingIndicator, TimeInput, TimePicker, Timeline, Toaster, Toggle, ToggleGroup, Tooltip, TooltipProvider, Truncated, ZoomableSvg, argoVariants, cn, computeDiffRows, computeLineInformation, copyToClipboard, isMac, kbdVariants, keys, mergeRefs, resolveStorybookBrand, setServerFieldErrors, themeToolbarBrands, toast, useAppForm, useAutosizeInput, useColorScheme, useInputOtpContext, useIsLegacyBrand, useMergeDiff, useNotification, useScrollbarPosition, useSidebar, useTheme, withForm };
14991
+ export { Alert, AnswerSummary, AppShell, AutoSaveTextarea, Avatar, Badge, Breadcrumb, Button, ButtonGroup, ButtonInline, Calendar, Card, Checkbox, Clipboard, ClipboardButton, ClipboardInline, Collapse, Collapsible, CollapsiblePanel, CollapsibleStepHeader, ColorInput, Combobox, Command, CommandGroup, CommandInput, CommandItem, CommandList, ConflictStatusIndicator, DateInput, DatePicker, DateRangeInput, DateRangePicker, DiffType, DiffView, DotsLoader, DropdownMenu, EmptyConfigurationActionCard, EmptySearchContent, EmptyState, ErrorState, FileUpload, FormGroup, FullScreenModal, FullScreenModalBody, FullScreenModalHeader, HelpBlock, HoverCard, InlineStepDetail, InlineStepLabel, InputGroup, InputOtp, Kbd, Label2 as Label, Link, MarkedText, MessageBubble, Modal, MultiActionButtonGroup, MultiCombobox, Navbar, NumberInput, PageHeader, PageLayout, PageToolbar, Pagination, PaneHeader, PanelWithDetails, PasswordInput, PlanApproval, PlanRewritingIndicator, Popconfirm, Popover, Progress, PromptInput, Question, QuestionBlock, RadioGroup2 as RadioGroup, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, ScrollBar, Search, SearchForm, SearchInput, SearchInputWithNavigation, Select, Separator2 as Separator, Sheet, Sidebar, SidebarProvider, Skeleton, SkeletonList, Slider, SplitButton, Stepper, SuggestedPrompt, Switch, Table, Tabs2 as Tabs, TabsContent, Tagger, TextInput, Textarea, ThemeDecorator, ThemeProvider, ThinkingIndicator, TimeInput, TimePicker, Timeline, Toaster, Toggle, ToggleGroup, Tooltip, TooltipProvider, Truncated, ZoomableSvg, argoVariants, cn, computeDiffRows, computeLineInformation, copyToClipboard, isMac, kbdVariants, keys, mergeRefs, resolveStorybookBrand, setServerFieldErrors, themeToolbarBrands, toast, useAppForm, useAutosizeInput, useColorScheme, useInputOtpContext, useIsLegacyBrand, useMergeDiff, useNotification, useScrollbarPosition, useSidebar, useTheme, withForm };
16131
14992
  //# sourceMappingURL=index.js.map
16132
14993
  //# sourceMappingURL=index.js.map