@keboola/design 13.0.2 → 13.1.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.
@@ -5,8 +5,8 @@ import { findLiteralMatches } from "./findLiteralMatches-DgGLzyG0.js";
5
5
  import { ClipboardButton } from "./ClipboardButton-srUgWgwH.js";
6
6
  import { useStableCallback } from "./internal/hooks/useStableCallback.js";
7
7
  import { HelpBlock } from "./internal/components/HelpBlock.js";
8
- import { useThemeAttributes } from "./useThemeAttributes-B199Regy.js";
9
8
  import { Kbd } from "./Kbd-J4n1J6i4.js";
9
+ import { useThemeAttributes } from "./useThemeAttributes-B199Regy.js";
10
10
  import { resolveToken } from "./themeTokens-7DEab0kp.js";
11
11
  import { useEffect, useLayoutEffect, useMemo, useRef } from "react";
12
12
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1018,4 +1018,4 @@ const CodeEditor = ({ value, previousValue, onChange, variant = "plain", mode =
1018
1018
  //#endregion
1019
1019
  export { CodeEditor, LANGUAGE_MODES, buildBaseThemeStyles, buildBasicSetup, buildCanvasChrome, buildChromeStyles, buildCustomTheme, buildDiffWash, isLanguageMode, searchExtension, updateSearch, useThemedExtension, useTooltipsExtension, useVariableCompletion };
1020
1020
 
1021
- //# sourceMappingURL=CodeEditor-jZMw1ioj.js.map
1021
+ //# sourceMappingURL=CodeEditor-Df7VVx08.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodeEditor-jZMw1ioj.js","names":["cmPlaceholder","placeholder"],"sources":["../src/components/CodeEditor/ButtonToolbar.tsx","../src/components/CodeEditor/modes/dbt.ts","../src/components/CodeEditor/modes/jsonnet.ts","../src/components/CodeEditor/diffWash.ts","../src/components/CodeEditor/syntaxPalette.ts","../src/components/CodeEditor/helpers.ts","../src/components/CodeEditor/editorChrome.ts","../src/components/CodeEditor/search.ts","../src/components/CodeEditor/ToggleComponentHelp.tsx","../src/components/CodeEditor/tokenTheme.ts","../src/components/CodeEditor/tooltips.ts","../src/components/CodeEditor/variableCompletion.ts","../src/components/CodeEditor/CodeEditor.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { ClipboardButton } from '../../blocks/ClipboardButton';\n\n// Floats over the top-right corner of the editor it is rendered into — private to\n// `CodeEditor`, which is the `relative` ancestor it positions against. `right-3`\n// leaves room for the scrollbar track, whose width the browser owns and no token\n// here describes.\nexport const ButtonToolbar = ({ value, children }: { value?: string; children?: ReactNode }) => {\n if (!value && !children) return null;\n\n return (\n <div className=\"tw:absolute tw:right-3 tw:top-1 tw:z-10 tw:flex tw:gap-0.5 tw:overflow-visible tw:rounded tw:border tw:border-solid tw:border-border tw:!bg-background tw:p-px tw:shadow-sm\">\n {!!value && <ClipboardButton size=\"icon-xs\" variant=\"invisible\" text={value} />}\n {children}\n </div>\n );\n};\n","import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';\nimport { simpleMode } from '@codemirror/legacy-modes/mode/simple-mode';\n\n// A dbt step is `dbt <command> [<subcommand>] [arguments, flags and selectors]`,\n// and the vocabulary below is grouped by the slot it belongs to — both to colour\n// it and to decide what is worth offering where.\nconst COMMANDS = [\n 'run-operation',\n 'run',\n 'test',\n 'seed',\n 'snapshot',\n 'list',\n 'ls',\n 'compile',\n 'build',\n 'deps',\n 'docs',\n 'source',\n];\nconst SUBCOMMANDS: Record<string, string[]> = { docs: ['generate'], source: ['freshness'] };\nconst ARGUMENTS = ['--select', '--exclude', '--selector', '--defer', '--resource-type', '-s'];\n// The arguments whose value is a graph selector, and so the only ones a selector\n// method has anything to attach to.\nconst SELECTORS = ['--select', '--exclude', '-s'];\nconst METHODS = [\n 'path:',\n 'source:',\n 'tag:',\n 'package:',\n 'config:',\n 'test_type:',\n 'test_name:',\n 'state:',\n 'exposure:',\n 'metric:',\n 'result:',\n 'source_status:',\n 'column_name:',\n];\nconst FLAGS = [\n '--fail-fast',\n '--warn-error',\n '--favor-state',\n '--vars',\n '--models',\n '--threads',\n '--profiles-dir',\n '--profile',\n '--full-refresh',\n];\n\n// A subcommand only ever highlights together with its command, so `dbt docs` stays\n// unpainted until `generate` follows it.\nconst COMMAND_PHRASES = COMMANDS.flatMap((command) => {\n const subcommands = SUBCOMMANDS[command];\n\n return subcommands ? subcommands.map((subcommand) => `${command} ${subcommand}`) : [command];\n});\n\n// Alternation is first-match, so a word that prefixes another has to come first\n// (`run-operation` before `run`, `--profiles-dir` before `--profile`). Sorting by\n// length keeps that true however the lists above are written.\nconst alternation = (list: string[]) => [...list].sort((a, b) => b.length - a.length).join('|');\n\n// Every keyword follows whitespace, so the leading run is part of the match.\n// Commands and arguments end on a word boundary; methods and flags carry their\n// own terminator (`:`) or need none.\nconst word = (list: string[]) => new RegExp(`^\\\\s+(?:${alternation(list)})\\\\b`, 'i');\nconst prefix = (list: string[]) => new RegExp(`^\\\\s+(?:${alternation(list)})`, 'i');\n\n// The word being completed: letters, digits, `_`, `-` and the `:` a selector\n// method ends with. Whitespace stays out of it, so a two-word label like `docs\n// generate` cannot stretch the match back across the words before the cursor.\nconst WORD = /[\\w:-]*$/;\n\nconst asOptions = (list: string[], type: string): Completion[] =>\n list.map((label) => ({ label, type }));\n\n// `type` drives the popup icon, so each group carries the one that matches the\n// colour the mode paints it in.\nconst DBT: Completion[] = [{ label: 'dbt', type: 'keyword' }];\nconst COMMAND_OPTIONS = asOptions(COMMANDS, 'keyword');\nconst SUBCOMMAND_OPTIONS: Record<string, Completion[]> = Object.fromEntries(\n Object.entries(SUBCOMMANDS).map(([command, subcommands]) => [\n command,\n asOptions(subcommands, 'keyword'),\n ]),\n);\nconst ARGUMENT_OPTIONS = asOptions(ARGUMENTS, 'variable');\nconst FLAG_OPTIONS = asOptions(FLAGS, 'constant');\nconst METHOD_OPTIONS = asOptions(METHODS, 'property');\n\n// Which slice of the vocabulary the cursor's slot can hold, given the words\n// already finished ahead of it. Offering the whole vocabulary everywhere proposes\n// `dbt` mid-command and a selector method with no selector to attach to.\nconst optionsAfter = (words: string[]): Completion[] => {\n const [step, command, ...rest] = words;\n\n if (step === undefined) return DBT;\n if (step.toLowerCase() !== 'dbt') return [];\n if (command === undefined) return COMMAND_OPTIONS;\n\n const subcommands = SUBCOMMAND_OPTIONS[command.toLowerCase()];\n if (subcommands && rest.length === 0) return subcommands;\n\n // A selector argument takes any number of space-separated values, so what\n // decides the slot is the last argument, not whether a selector appeared at all:\n // `--select tag:a tag:b` keeps offering methods, `--select a --profile p` stops.\n const lastArgument = rest.filter((it) => it.startsWith('-')).at(-1);\n const selecting = lastArgument !== undefined && SELECTORS.includes(lastArgument.toLowerCase());\n\n return selecting\n ? [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS, ...METHOD_OPTIONS]\n : [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS];\n};\n\nconst complete = (context: CompletionContext): CompletionResult | null => {\n const typed = context.matchBefore(WORD);\n\n // `WORD` also matches the empty string, so without this the popup would open on\n // every space. Asking for completions explicitly still opens it there.\n if (!typed?.text && !context.explicit) return null;\n\n const from = typed?.from ?? context.pos;\n const line = context.state.doc.lineAt(from);\n const options = optionsAfter(\n line.text\n .slice(0, from - line.from)\n .split(/\\s+/)\n .filter(Boolean),\n );\n\n return options.length > 0 ? { from, options, validFor: WORD } : null;\n};\n\nexport const dbt = simpleMode({\n languageData: {\n // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.\n commentTokens: { line: '--', block: { open: '/*', close: '*/' } },\n autocomplete: complete,\n },\n start: [\n { regex: /\"(?:[^\\\\]|\\\\.)*?(?:\"|$)/, token: 'string' },\n // Word-bounded, so `dbtX` is not a dbt step whose first word happens to\n // colour — the same thing the completion source asks of it.\n { regex: /dbt\\b/, token: 'keyword', sol: true },\n { regex: word(COMMAND_PHRASES), token: 'keyword' },\n { regex: word(ARGUMENTS), token: 'variableName' },\n { regex: prefix(METHODS), token: 'propertyName' },\n { regex: prefix(FLAGS), token: 'attributeName' },\n { regex: /(?:@|\\*|,|\\+\\d+|\\d+\\+|\\+)/, token: 'operator' },\n { regex: /'.*'/, token: 'string' },\n { regex: /true|false/, token: 'atom' },\n ],\n});\n","import type { StreamParser } from '@codemirror/language';\n\n/**\n * Port of google/codemirror-mode-jsonnet (Apache-2.0) to CodeMirror 6 tags.\n *\n * - Patterns are anchored with `^`: unanchored, `StringStream.match` scans the whole rest of the line.\n */\n\nconst COMMENT_END = /^\\*\\//;\nconst COMMENT_START = /^\\/\\/|^#/;\nconst C_COMMENT_START = /^\\/\\*/;\nconst TEXT_BLOCK = /^\\|\\|\\|/;\nconst TEXT_BLOCK_END = /^\\s*\\|\\|\\|/;\nconst RAW_DOUBLE = /^\"\"/;\nconst RAW_SINGLE = /^''/;\nconst CLOSE_DOUBLE = /^\"/;\nconst CLOSE_SINGLE = /^'/;\nconst ESCAPE = /^\\\\[\\\\\"'/bfnrt0]/;\nconst UNICODE_ESCAPE = /^\\\\u[0-9a-fA-F]{4}/;\nconst BACKSLASH = /^\\\\/;\nconst IMPORT = /^import(?:str)?\\s*(@?)([\"'])/;\nconst QUOTE = /^(@?)([\"'])/;\nconst ROOT = /^\\$/;\nconst NUMBER = /^(?:\\.\\d+|\\d+\\.?\\d*)(?:e[-+]?\\d+)?/i;\nconst OPERATOR = /^[-+/*=<>!&~^|$%]+/;\nconst IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*/;\n\nconst KEYWORDS: Record<string, 'keyword' | 'atom'> = {\n local: 'keyword',\n self: 'keyword',\n super: 'keyword',\n assert: 'keyword',\n function: 'keyword',\n if: 'keyword',\n then: 'keyword',\n else: 'keyword',\n for: 'keyword',\n in: 'keyword',\n tailstrict: 'keyword',\n error: 'keyword',\n true: 'atom',\n false: 'atom',\n null: 'atom',\n};\n\ntype State = {\n cComment: boolean;\n textBlock: boolean;\n textBlockIndent: number | null;\n string: boolean;\n importString: boolean;\n stringSingle: boolean;\n stringRaw: boolean;\n};\n\nexport const jsonnet: StreamParser<State> = {\n name: 'jsonnet',\n\n // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.\n languageData: { commentTokens: { line: '//', block: { open: '/*', close: '*/' } } },\n\n startState: () => ({\n cComment: false,\n textBlock: false,\n textBlockIndent: null,\n string: false,\n importString: false,\n stringSingle: false,\n stringRaw: false,\n }),\n\n token: (stream, state) => {\n if (state.cComment) {\n if (stream.match(COMMENT_END)) {\n state.cComment = false;\n return 'comment';\n }\n stream.next();\n return 'comment';\n }\n\n // Match the closing `|||` before measuring indent, or a block closed at column 0 never ends.\n if (state.textBlock) {\n if (state.textBlockIndent == null) {\n if (stream.match(TEXT_BLOCK_END)) {\n state.textBlock = false;\n return 'string';\n }\n state.textBlockIndent = stream.indentation();\n }\n if (stream.indentation() >= state.textBlockIndent) {\n stream.skipToEnd();\n return 'string';\n }\n if (stream.match(TEXT_BLOCK_END)) {\n state.textBlock = false;\n return 'string';\n }\n stream.next();\n return 'invalid';\n }\n\n if (state.string || state.importString) {\n const style = state.string ? 'string' : 'meta';\n\n if (state.stringRaw) {\n if (stream.match(state.stringSingle ? RAW_SINGLE : RAW_DOUBLE)) return 'escape';\n } else {\n if (stream.match(ESCAPE)) return 'escape';\n if (stream.match(UNICODE_ESCAPE)) return 'escape';\n if (stream.match(BACKSLASH)) return 'invalid';\n }\n\n if (stream.match(state.stringSingle ? CLOSE_SINGLE : CLOSE_DOUBLE)) {\n state.string = false;\n state.importString = false;\n return style;\n }\n\n stream.next();\n return style;\n }\n\n if (stream.match(COMMENT_START)) {\n stream.skipToEnd();\n return 'comment';\n }\n if (stream.match(C_COMMENT_START)) {\n state.cComment = true;\n return 'comment';\n }\n\n const imported = stream.match(IMPORT);\n if (Array.isArray(imported)) {\n state.importString = true;\n state.stringRaw = imported[1] === '@';\n state.stringSingle = imported[2] === \"'\";\n return 'meta';\n }\n\n const quoted = stream.match(QUOTE);\n if (Array.isArray(quoted)) {\n state.string = true;\n state.stringRaw = quoted[1] === '@';\n state.stringSingle = quoted[2] === \"'\";\n return 'string';\n }\n\n if (stream.match(TEXT_BLOCK)) {\n state.textBlock = true;\n state.textBlockIndent = null;\n return 'string';\n }\n\n if (stream.match(ROOT)) return 'keyword';\n if (stream.match(NUMBER)) return 'number';\n if (stream.match(OPERATOR)) return 'operator';\n\n // Consumed whole so that a keyword's prefix (`locally`) is not styled.\n const identifier = stream.match(IDENTIFIER);\n if (Array.isArray(identifier)) return KEYWORDS[identifier[0]] ?? null;\n\n stream.next();\n return null;\n },\n};\n","import type { ResolvedColorScheme } from '../ThemeProvider/types';\n\n/**\n * Alpha suffixes for the dark-scheme diff and state tints.\n *\n * - Line fill stays subtle for text to read; the gutter sits a step stronger.\n * - `DARK_LINE_ALPHA` is also appended by the static washes in `highlighting.ts` and `search.ts`.\n */\nexport const DARK_LINE_ALPHA = '29'; /* 16% */\nconst DARK_GUTTER_ALPHA = '47'; /* 28% */\n\n/**\n * The two diff fills per scheme: light uses the opaque pastel, dark the `500` hue at low alpha.\n *\n * - Imports nothing, so `MergeEditor` shares it without pulling in CodeMirror via `helpers.ts`.\n * - Shared by `helpers.ts` and `MergeEditor/decorations.ts`, so their alphas cannot drift.\n */\nexport const buildDiffWash = (scheme: ResolvedColorScheme) => {\n const dark = scheme === 'dark';\n\n return {\n line: (hue: string, pastel: string) => (dark ? `${hue}${DARK_LINE_ALPHA}` : pastel),\n gutter: (hue: string, pastel: string) => (dark ? `${hue}${DARK_GUTTER_ALPHA}` : pastel),\n };\n};\n","import { tags } from '@lezer/highlight';\n\nimport colors from '@keboola/tailwind-config/colors';\n\nimport type { ResolvedColorScheme } from '../ThemeProvider/types';\n\n/**\n * The tag colours layered over the stock github palette, per colour scheme.\n *\n * - Imports only tags and ramps, so `scripts/contrast-audit.ts` can measure it.\n * - These override stock rules for the same tag.\n * - Colours are chosen against `background` and `muted` (`variant=\"field\"`); ratios quote both.\n */\nexport const buildSyntaxPalette = (scheme: ResolvedColorScheme, foreground: string) => {\n const dark = scheme === 'dark';\n\n return [\n // Identifiers and brackets carry no colour, as on github.com.\n { tag: [tags.name, tags.special(tags.string), tags.bracket], color: foreground },\n // Functions — light `600` 6.13 / 5.84, dark `300` 9.62 / 7.80.\n { tag: tags.standard(tags.name), color: dark ? colors.purple[300] : colors.purple[600] },\n // Special vars — light `800` 7.26 / 6.92, dark `300` 13.49 / 10.94.\n { tag: tags.special(tags.name), color: dark ? colors.cyan[300] : colors.cyan[800] },\n // Strings — light `800` 7.23 / 6.89, dark `300` 13.53 / 10.97.\n { tag: tags.string, color: dark ? colors.warning[300] : colors.warning[800] },\n // Light-only fixes for stock colours below AA; `CONTRAST-AUDIT.md` has all surfaces.\n ...(dark\n ? []\n : [\n // Keywords — 5.96 / 5.69.\n { tag: [tags.keyword, tags.typeName, tags.typeOperator], color: colors.error[550] },\n // Comments — 6.44 / 6.15.\n { tag: tags.comment, color: colors.neutral[500] },\n // Markdown quotes — 7.15 / 6.82.\n { tag: tags.quote, color: colors.green[900] },\n // Lex errors — 7.81 / 7.45; stock red fails the read-only wash.\n { tag: tags.invalid, color: colors.error[700] },\n ]),\n // Dark only: `githubDarkStyle` has no `escape` rule, so escapes would blend into strings.\n ...(dark ? [{ tag: [tags.escape, tags.url, tags.link], color: colors.blue[300] }] : []),\n ];\n};\n","import { javascript } from '@codemirror/lang-javascript';\nimport { json, jsonParseLinter } from '@codemirror/lang-json';\nimport { python } from '@codemirror/lang-python';\nimport { MSSQL, MySQL, PLSQL, PostgreSQL, StandardSQL } from '@codemirror/lang-sql';\nimport { StreamLanguage } from '@codemirror/language';\nimport { r } from '@codemirror/legacy-modes/mode/r';\nimport { shell } from '@codemirror/legacy-modes/mode/shell';\nimport { toml } from '@codemirror/legacy-modes/mode/toml';\nimport type { LintSource } from '@codemirror/lint';\nimport { linter } from '@codemirror/lint';\nimport { githubDarkInit, githubLightInit } from '@uiw/codemirror-theme-github';\nimport type { BasicSetupOptions } from '@uiw/react-codemirror';\n\nimport { getSqlLanguageSupport } from '@keboola/codemirror-lang-sql';\nimport colors from '@keboola/tailwind-config/colors';\n\nimport { resolveToken } from '../../utils/themeTokens';\nimport type { ResolvedColorScheme } from '../ThemeProvider/types';\n\nimport { dbt } from './modes/dbt';\nimport { jsonnet } from './modes/jsonnet';\nimport { buildDiffWash } from './diffWash';\nimport { buildSyntaxPalette } from './syntaxPalette';\n\n// One list for both the runtime whitelist and the type — a separate `LANGUAGE_MODE[]` copy drifts.\nexport const LANGUAGE_MODES = [\n 'application/json',\n 'text/plain',\n 'text/x-python',\n 'text/x-sql',\n 'text/x-mysql',\n 'text/x-pgsql',\n 'text/x-mssql',\n // Snowflake; the strings are a published prop contract.\n 'text/x-sfsql',\n 'text/x-bqsql',\n 'text/x-plsql',\n 'text/x-rsrc',\n 'text/x-sh',\n 'text/x-toml',\n 'text/jsonnet',\n 'text/x-dbt',\n 'text/javascript',\n 'text/typescript',\n] as const;\n\nexport type LANGUAGE_MODE = (typeof LANGUAGE_MODES)[number];\n\nexport const isLanguageMode = (mode: string): mode is LANGUAGE_MODE =>\n (LANGUAGE_MODES as readonly string[]).includes(mode);\n\n// - `readOnly` is only addressable through `contenteditable`.\n// - `fieldChrome` overrides the read-only wash by re-declaring this key; strings must match exactly.\nexport const READ_ONLY_EDITOR = '&.cm-editor:has(.cm-content[contenteditable=\"false\"])';\nexport const EDITABLE_EDITOR = '&.cm-editor:has(.cm-content[contenteditable=\"true\"])';\n\n/**\n * Editor chrome and the unified merge (diff) wash.\n *\n * - Chrome resolves from live `--*` tokens; fallbacks mirror light-mode values for SSR.\n * - Diff colours are fixed across brands; light/dark pairs from `buildDiffWash`, shared with\n * `MergeEditor/decorations.ts`.\n * - Only `CodeEditor`'s unified merge view uses this; `MergePane` has its own theme.\n */\nexport const buildBaseThemeStyles = (scheme: ResolvedColorScheme) => {\n const { line, gutter } = buildDiffWash(scheme);\n const dark = scheme === 'dark';\n\n return {\n '*': { lineHeight: '20px' },\n '*::selection': {\n backgroundColor: resolveToken('primary', '31 143 255'),\n color: `${resolveToken('primary-foreground', '255 255 255')} !important`,\n },\n // Dark uses `muted`: `secondary` is lighter there and drops `comment` to 4.27:1.\n // `--code-editor-surface` on an ancestor overrides body and gutters.\n [READ_ONLY_EDITOR]: {\n backgroundColor: `var(--code-editor-surface, ${\n dark ? resolveToken('muted', '38 38 45') : resolveToken('secondary', '226 232 240')\n })`,\n },\n [`${READ_ONLY_EDITOR} .cm-gutters`]: {\n backgroundColor: `var(--code-editor-surface, ${resolveToken('border', '229 231 235')})`,\n },\n '&.cm-editor .cm-scroller': { overflowAnchor: 'none' },\n '&.cm-editor, &.cm-editor .cm-scroller': {\n minHeight: '100%',\n flexGrow: 1,\n alignItems: 'stretch !important',\n outline: 'none',\n },\n '.cm-gutter.cm-foldGutter': { display: 'none !important' },\n '.cm-gutter.cm-lineNumbers': { paddingLeft: '20px', paddingRight: '6px' },\n '.cm-gutters': { height: 'auto' },\n\n // merge (diff) view\n '&[class*=\"cm-merge-\"] .cm-deletedLine': {\n backgroundColor: line(colors.error[500], colors.error[100]),\n },\n '&[class*=\"cm-merge-\"] .cm-changedLine': {\n backgroundColor: line(colors.green[500], colors.green[100]),\n },\n '&[class*=\"cm-merge-\"] .cm-deletedLineGutter': {\n backgroundColor: gutter(colors.error[500], colors.error[200]),\n },\n '&[class*=\"cm-merge-\"] .cm-changedLineGutter': {\n backgroundColor: gutter(colors.green[500], colors.green[200]),\n },\n '&[class*=\"cm-merge-\"] .cm-deletedText': {\n background: gutter(colors.error[500], colors.error[200]),\n },\n '&[class*=\"cm-merge-\"] .cm-changedText': {\n background: gutter(colors.green[500], colors.green[200]),\n },\n // Follows the page, not the diff — fixed white would be a light slab under dark.\n '&[class*=\"cm-merge-\"]': {\n backgroundColor: `${resolveToken('background', '249 250 251')} !important`,\n },\n '&[class*=\"cm-merge-\"] .cm-gutters': {\n backgroundColor: `${resolveToken('muted', '241 245 249')} !important`,\n },\n '.cm-changeGutter': { position: 'absolute', zIndex: -1, width: '100%', paddingLeft: 0 },\n '&[class*=\"cm-merge-\"] .cm-changedLine,&[class*=\"cm-merge-\"] .cm-line, &[class*=\"cm-merge-\"] .cm-deletedChunk':\n { paddingLeft: 0 },\n };\n};\n\n// - Fold gutter and active line are hidden by the themes anyway.\n// - `autocompletion`: `CodeEditor` and `SqlEditor` install their own; a second instance competes.\nconst ALWAYS_OFF = {\n autocompletion: false,\n drawSelection: false,\n foldGutter: false,\n foldKeymap: false,\n highlightActiveLine: false,\n highlightActiveLineGutter: false,\n} as const;\n\n// - `basicSetup` enables everything not skipped; a viewer drops editing commands.\n// - Search stays — Mod-f is useful on a viewer.\n// - `history` stays: flipping `readOnly` reconfigures the view, which would drop the undo stack.\nexport const buildBasicSetup = (readOnly: boolean): BasicSetupOptions => ({\n ...ALWAYS_OFF,\n ...(readOnly\n ? {\n closeBrackets: false,\n closeBracketsKeymap: false,\n lintKeymap: false,\n indentOnInput: false,\n rectangularSelection: false,\n dropCursor: false,\n highlightSelectionMatches: false,\n }\n : null),\n});\n\n/**\n * The syntax theme, per colour scheme.\n *\n * - Light github palette fails AA on dark surfaces, so the palette is picked by scheme.\n * - `githubDarkInit` sets the `EditorView.darkTheme` facet that every `&dark` rule keys off.\n * - `caret` and `selectionMatch` are pinned: the initialisers disagree on them.\n */\nexport const buildCustomTheme = (scheme: ResolvedColorScheme) => {\n const foreground = resolveToken('foreground', '30 41 59');\n const init = scheme === 'dark' ? githubDarkInit : githubLightInit;\n\n return init({\n settings: {\n fontFamily: `'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New'`,\n background: resolveToken('background', '249 250 251'),\n foreground,\n caret: foreground,\n gutterBackground: resolveToken('muted', '241 245 249'),\n gutterForeground: resolveToken('muted-foreground', '100 116 139'),\n gutterBorder: 'transparent',\n lineHighlight: 'transparent',\n selection: resolveToken('primary', '31 143 255'),\n selectionMatch: resolveToken('primary', '31 143 255', 0.1),\n },\n styles: buildSyntaxPalette(scheme, foreground),\n });\n};\n\nexport const getLanguageMode = (mode?: LANGUAGE_MODE) => {\n switch (mode) {\n case undefined:\n case 'application/json':\n return json();\n case 'text/x-python':\n return python();\n case 'text/x-sql':\n return getSqlLanguageSupport(StandardSQL);\n case 'text/x-mysql':\n return getSqlLanguageSupport(MySQL);\n case 'text/x-pgsql':\n return getSqlLanguageSupport(PostgreSQL);\n case 'text/x-mssql':\n return getSqlLanguageSupport(MSSQL);\n case 'text/x-sfsql':\n return getSqlLanguageSupport('snowflake');\n case 'text/x-bqsql':\n return getSqlLanguageSupport('bigquery');\n case 'text/x-plsql':\n return getSqlLanguageSupport(PLSQL);\n case 'text/x-rsrc':\n return StreamLanguage.define(r);\n case 'text/x-sh':\n return StreamLanguage.define(shell);\n case 'text/x-toml':\n return StreamLanguage.define(toml);\n case 'text/jsonnet':\n return StreamLanguage.define(jsonnet);\n case 'text/x-dbt':\n return StreamLanguage.define(dbt);\n case 'text/javascript':\n return javascript({ jsx: true });\n case 'text/typescript':\n return javascript({ jsx: true, typescript: true });\n // `text/plain` and any unmapped mode: unstyled, not coloured as JSON.\n default:\n return [];\n }\n};\n\n// A read-only editor can't act on lint errors; its underlines are noise.\nexport const shouldLintJson = (mode: LANGUAGE_MODE | undefined, readOnly: boolean): boolean =>\n mode === 'application/json' && !readOnly;\n\n/**\n * Wraps a lint source so a blank document produces no diagnostics.\n *\n * - For optional fields, where empty is valid but `jsonParseLinter` reports an error.\n */\nexport const skipBlankDocument =\n (source: LintSource): LintSource =>\n (view) =>\n view.state.doc.toString().trim() === '' ? [] : source(view);\n\n/**\n * The JSON linter, optionally blind to a blank document.\n *\n * - Opt-in: some callers rely on the marker alone to explain why empty disables their button.\n * - Not derivable from `variant` — whether blank is valid is the field's contract.\n */\nexport const buildJsonLinter = (allowBlankDocument: boolean) => {\n const source = jsonParseLinter();\n\n return linter(allowBlankDocument ? skipBlankDocument(source) : source);\n};\n","import { resolveToken } from '../../utils/themeTokens';\n\nimport { EDITABLE_EDITOR, READ_ONLY_EDITOR } from './helpers';\n\n/** Per-preset parts of an editor's outer chrome, mapped to selectors by `buildChromeStyles`. */\nexport type EditorChrome = {\n surface: string;\n borderColor: string;\n readOnlySurface: string;\n readOnlyBorderColor: string;\n /** `null`: no hover affordance (form inputs). */\n hoverBorderColor: string | null;\n focusBorderColor: string;\n focusRing: string;\n radius: string;\n paddingY: string;\n /** `null` leaves CodeMirror's own 6px/2px line inset alone. */\n paddingX: { left: string; right: string } | null;\n};\n\n/**\n * Mirrors `InputGroup` at each design language's `TextInput` sizing, so it reads as a form field.\n *\n * - Same colour-scheme tokens as `InputGroup`, so it follows light/dark.\n * - argo: `muted`/`input`, the editable argo field's pair.\n * - legacy: `secondary` as `variant=\"secondary\"`; readonly `muted`/`input` as base `InputGroup`.\n */\nexport const buildInputChrome = (isArgo: boolean): EditorChrome => {\n return {\n surface: isArgo\n ? resolveToken('muted', '241 245 249')\n : resolveToken('secondary', '226 232 240'),\n borderColor: isArgo\n ? resolveToken('input', '203 213 225')\n : resolveToken('secondary', '226 232 240'),\n readOnlySurface: resolveToken('muted', '241 245 249'),\n readOnlyBorderColor: resolveToken('input', '203 213 225'),\n hoverBorderColor: null,\n focusBorderColor: isArgo\n ? resolveToken('primary', '37 99 235')\n : resolveToken('ring', '31 143 255'),\n focusRing: `0 0 0 4px ${resolveToken('ring', '31 143 255', isArgo ? 0.5 : 0.3)}`,\n radius: isArgo ? 'var(--radius-lg, 0.25rem)' : '0.25rem',\n // 2px border + 2×this + `.cm-content`'s 4px + 20px line = a one-line `TextInput`:\n // argo `medium` (36px), legacy `default` (40px).\n paddingY: isArgo ? '3px' : '5px',\n // Tops `.cm-line`'s 6px/2px up to an input's 16px text inset.\n paddingX: { left: '10px', right: '14px' },\n };\n};\n\n/** The SQL workspace's notebook cell: a white canvas, not a form control. */\nexport const buildCanvasChrome = (): EditorChrome => ({\n surface: resolveToken('card', '255 255 255'),\n borderColor: 'transparent',\n readOnlySurface: resolveToken('muted', '241 245 249'),\n readOnlyBorderColor: 'transparent',\n hoverBorderColor: resolveToken('ring', '31 143 255'),\n focusBorderColor: resolveToken('ring', '31 143 255'),\n focusRing: `0 0 0 4px ${resolveToken('ring', '31 143 255', 0.3)}`,\n radius: '8px',\n paddingY: '8px',\n paddingX: null,\n});\n\n/** Spread over `buildBaseThemeStyles()`; read-only keys match the base's to replace its wash. */\nexport const buildChromeStyles = (chrome: EditorChrome) => ({\n '&.cm-editor': {\n border: `solid 1px ${chrome.borderColor}`,\n borderRadius: chrome.radius,\n backgroundColor: chrome.surface,\n paddingTop: chrome.paddingY,\n paddingBottom: chrome.paddingY,\n },\n '&.cm-editor :is(.cm-gutters,.cm-scroller)': { backgroundColor: chrome.surface },\n\n ...(chrome.paddingX\n ? {\n // Gutterless only: text aligns with a neighbouring `TextInput`'s; a gutter owns the edge.\n '&.cm-editor:not(:has(.cm-gutters)) .cm-content': {\n paddingLeft: chrome.paddingX.left,\n paddingRight: chrome.paddingX.right,\n },\n }\n : null),\n\n ...(chrome.hoverBorderColor\n ? { [`${EDITABLE_EDITOR}:hover`]: { borderColor: chrome.hoverBorderColor } }\n : null),\n [`${EDITABLE_EDITOR}:focus-within`]: {\n borderColor: chrome.focusBorderColor,\n boxShadow: chrome.focusRing,\n },\n\n [READ_ONLY_EDITOR]: {\n backgroundColor: chrome.readOnlySurface,\n borderColor: chrome.readOnlyBorderColor,\n },\n [`${READ_ONLY_EDITOR} .cm-gutters`]: { backgroundColor: chrome.readOnlySurface },\n [`${READ_ONLY_EDITOR} .cm-scroller`]: { backgroundColor: chrome.readOnlySurface },\n});\n","import { StateEffect, StateField, type Text } from '@codemirror/state';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n ViewPlugin,\n type ViewUpdate,\n} from '@codemirror/view';\n\nimport colors from '@keboola/tailwind-config/colors';\n\nimport { findLiteralMatches } from '../../utils/findLiteralMatches';\n\nimport { DARK_LINE_ALPHA } from './diffWash';\n\ntype SearchMatch = {\n from: number;\n to: number;\n localIndex: number;\n};\n\nconst setSearchEffect = StateEffect.define<{\n query: string;\n selectedMatchIndex?: number;\n}>();\n\ntype SearchState = {\n query: string;\n selectedMatchIndex?: number;\n matches: SearchMatch[];\n decorations: DecorationSet;\n};\n\nfunction findMatches(doc: Text, query: string): SearchMatch[] {\n // Before `doc.toString()`, which joins the whole rope.\n if (!query || query.length > doc.length) return [];\n\n return findLiteralMatches(doc.toString(), query).map((from, index) => ({\n from,\n to: from + query.length,\n localIndex: index,\n }));\n}\n\nfunction createDecorations(matches: SearchMatch[], selectedLocalIndex?: number): DecorationSet {\n const decorations = matches.map((match) => {\n const isSelected = match.localIndex === selectedLocalIndex;\n\n const decoration = Decoration.mark({\n class: isSelected ? 'cm-searchMatch-selected' : 'cm-searchMatch',\n });\n\n return decoration.range(match.from, match.to);\n });\n\n return Decoration.set(decorations, true);\n}\n\nconst searchField = StateField.define<SearchState>({\n create() {\n return {\n query: '',\n selectedMatchIndex: undefined,\n matches: [],\n decorations: Decoration.none,\n };\n },\n\n update(state, tr) {\n let newState = state;\n\n for (const effect of tr.effects) {\n if (!effect.is(setSearchEffect)) {\n continue;\n }\n\n const { query, selectedMatchIndex } = effect.value;\n\n const matches = findMatches(tr.state.doc, query);\n\n const decorations = createDecorations(matches, selectedMatchIndex);\n\n newState = {\n query,\n selectedMatchIndex,\n matches,\n decorations,\n };\n }\n\n if (tr.docChanged && newState.query) {\n const matches = findMatches(tr.state.doc, newState.query);\n const decorations = createDecorations(matches, newState.selectedMatchIndex);\n\n newState = {\n ...newState,\n matches,\n decorations,\n };\n }\n\n return newState;\n },\n\n provide: (field) => EditorView.decorations.from(field, (state) => state.decorations),\n});\n\nconst searchViewPlugin = ViewPlugin.fromClass(\n class {\n private lastSelectedIndex?: number;\n\n update(update: ViewUpdate) {\n const state = update.state.field(searchField);\n\n if (\n state.selectedMatchIndex !== undefined &&\n state.selectedMatchIndex !== this.lastSelectedIndex\n ) {\n const match = state.matches[state.selectedMatchIndex];\n\n if (match) {\n requestAnimationFrame(() => {\n update.view.dispatch({\n effects: EditorView.scrollIntoView(match.from, { y: 'center' }),\n });\n });\n }\n\n this.lastSelectedIndex = state.selectedMatchIndex;\n }\n\n if (state.selectedMatchIndex === undefined) {\n this.lastSelectedIndex = undefined;\n }\n }\n },\n);\n\n/**\n * Match and current-match fills, per colour scheme.\n *\n * - `&dark` keeps this a static base theme; it applies when the `EditorView.darkTheme` facet is set.\n * - Dark current match uses `neutral[900]` text: white on `blue[500]` is 2.55:1.\n */\nconst searchTheme = EditorView.baseTheme({\n '.cm-searchMatch': {\n backgroundColor: colors.blue[100],\n },\n '.cm-searchMatch > span': {\n color: `${colors.blue[700]} !important`,\n },\n '.cm-searchMatch-selected': {\n backgroundColor: colors.blue[700],\n },\n '.cm-searchMatch-selected > span': {\n color: `${colors.white} !important`,\n },\n\n '&dark .cm-searchMatch': {\n backgroundColor: `${colors.blue[500]}${DARK_LINE_ALPHA}`,\n },\n '&dark .cm-searchMatch > span': {\n color: `${colors.blue[200]} !important`,\n },\n '&dark .cm-searchMatch-selected': {\n backgroundColor: colors.blue[500],\n },\n '&dark .cm-searchMatch-selected > span': {\n color: `${colors.neutral[900]} !important`,\n },\n});\n\nexport function searchExtension() {\n return [searchField, searchViewPlugin, searchTheme];\n}\n\nexport function updateSearch(view: EditorView, query: string, selectedMatchIndex?: number) {\n view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });\n}\n","import { isMac } from '../../utils';\nimport { Kbd } from '../Kbd';\n\nexport const ToggleComponentHelp = () => (\n <div>\n Use <Kbd>{isMac ? 'Command+/' : 'Ctrl+/'}</Kbd> to toggle comments.\n </div>\n);\n","import { type Extension } from '@codemirror/state';\n\nimport type { ResolvedColorScheme } from '../ThemeProvider/types';\nimport { useThemeAttributes } from '../ThemeProvider/useThemeAttributes';\n\n// Shared across instances: each theme's StyleModule appends rules to a document-level\n// stylesheet, so one module per theme keeps it constant-size however many editors mount.\nconst themeCache = new Map<string, Extension>();\n\n/**\n * A CodeMirror extension shared per `cacheKey`, rebuilt when the brand or light/dark mode changes.\n *\n * - `build` reads live `--*` values off `<html>`, a dependency no deps array can see.\n * - `scheme` comes from the same read as the key, for values that are a light/dark pair.\n * - `cacheKey` must include everything `build` closes over, or different inputs share a theme.\n */\nexport const useThemedExtension = (\n cacheKey: string,\n build: (scheme: ResolvedColorScheme) => Extension,\n): Extension => {\n const { scheme, cacheKey: themeKey } = useThemeAttributes();\n const key = `${themeKey} ${cacheKey}`;\n\n // Filling the module cache during render is idempotent.\n let cached = themeCache.get(key);\n if (!cached) {\n cached = build(scheme);\n themeCache.set(key, cached);\n }\n\n return cached;\n};\n","import { useMemo } from 'react';\nimport { Compartment, type Extension } from '@codemirror/state';\nimport { tooltips, ViewPlugin } from '@codemirror/view';\n\n// Whether this element becomes the containing block of a `position: fixed` descendant.\n// - Encodes the full CSS rule; `contain` and `will-change` are value lists, matched loosely.\n// - `content-visibility` is left to `crops`, the stronger of the two for our purposes.\nconst establishesFixedContainingBlock = (style: CSSStyleDeclaration) =>\n style.transform !== 'none' ||\n style.translate !== 'none' ||\n style.rotate !== 'none' ||\n style.scale !== 'none' ||\n style.perspective !== 'none' ||\n style.filter !== 'none' ||\n style.backdropFilter !== 'none' ||\n /\\b(paint|layout|strict|content)\\b/.test(style.contain) ||\n /\\b(transform|perspective|filter|contain)\\b/.test(style.willChange);\n\n// Crops even a fixed-position descendant; `content-visibility: auto` implies paint\n// containment without showing it in computed `contain`.\nconst crops = (style: CSSStyleDeclaration) =>\n style.overflowX !== 'visible' ||\n style.overflowY !== 'visible' ||\n style.maskImage !== 'none' ||\n style.contentVisibility !== 'visible' ||\n /\\b(paint|strict|content)\\b/.test(style.contain);\n\n/**\n * Where a tooltip can hang uncropped, or `null` for CodeMirror's default.\n *\n * - Hosts above the outermost cropper.\n * - Stops at the fixed containing block; nothing higher can crop.\n * - `<body>` and `<html>` never count as croppers.\n */\nconst findTooltipHost = (from: HTMLElement) => {\n let outermostCropper: HTMLElement | null = null;\n\n for (let node = from.parentElement; node && node !== document.body; node = node.parentElement) {\n const style = getComputedStyle(node);\n\n if (crops(style)) {\n outermostCropper = node;\n } else if (establishesFixedContainingBlock(style)) {\n return outermostCropper?.parentElement ?? node;\n }\n }\n\n return outermostCropper?.parentElement ?? null;\n};\n\n/**\n * `tooltips()`, re-hosted so the completion popup is never cropped.\n *\n * - Must survive a masked, scrolling `Modal` and kbc-ui's `content-visibility: auto` blocks.\n * - Not `document.body`: the popup would sit behind the modal, which disables pointer events there.\n * - The only tooltip host in either editor: CodeMirror takes the first parent configured.\n */\nconst tooltipsExtension = (): Extension => {\n // A compartment, because a prop-driven full reconfigure drops appended config but keeps compartments.\n const layer = new Compartment();\n\n return [\n layer.of(tooltips()),\n ViewPlugin.define((view) => {\n // Deferred: a plugin cannot dispatch while its view is being built, and reading styles\n // here would force a layout flush mid-commit. One-shot; later ancestor changes are missed.\n const scheduled = setTimeout(() => {\n if (!view.dom.isConnected) return;\n\n const parent = findTooltipHost(view.dom);\n if (parent) view.dispatch({ effects: layer.reconfigure(tooltips({ parent })) });\n });\n\n return { destroy: () => clearTimeout(scheduled) };\n }),\n ];\n};\n\n/**\n * The tooltips extension, built once per editor; a rebuild would drop the resolved host.\n */\nexport const useTooltipsExtension = () => useMemo(tooltipsExtension, []);\n","import type { Completion, CompletionContext, CompletionSource } from '@codemirror/autocomplete';\n\nimport { useStableCallback } from '../../hooks/useStableCallback';\n\nexport type EditorVariable = { name: string; value?: string };\n\n// Ranks variables above the language's many same-prefix keywords.\nconst BOOST = 2000;\n\n// - One brace or two: `closeBrackets` turns a typed `{` into `{}`.\n// - One name charset throughout; a narrower second one would start the range mid-name and never match.\nconst NAME = String.raw`[\\w-]*`;\nconst AT_CARET = new RegExp(String.raw`(?:\\{{1,2} ?)?${NAME}$`);\nconst NAME_AT_END = new RegExp(`${NAME}$`);\nconst OPENING = /\\{{1,2} ?$/;\nconst CLOSING = /^ ?\\}{1,2}/;\n\n/**\n * Completes a mustache-style `{{name}}` placeholder.\n */\nexport const completeVariables = (variables: EditorVariable[] = []): CompletionSource => {\n if (variables.length === 0) return () => null;\n\n const options: Completion[] = variables.map(({ name, value }) => ({\n // Bare name: the only spelling both editors' filters match, braces typed or not.\n label: name,\n displayLabel: `{{${name}}}`,\n detail: value,\n type: 'variable',\n boost: BOOST,\n apply: (view, completion, from, to) => {\n const { doc } = view.state;\n const line = doc.lineAt(from);\n const insert = `{{${completion.label}}}`;\n\n // Braces are found, not assumed: `closeBrackets` may have added a closing one.\n const opening = OPENING.exec(doc.sliceString(line.from, from));\n const closing = CLOSING.exec(doc.sliceString(to, line.to));\n const start = opening ? from - opening[0].length : from;\n const end = closing ? to + closing[0].length : to;\n\n view.dispatch({\n changes: { from: start, to: end, insert },\n selection: { anchor: start + insert.length },\n });\n },\n }));\n\n return (context: CompletionContext) => {\n const match = context.matchBefore(AT_CARET);\n\n if (!match?.text) return null;\n\n const [name = ''] = NAME_AT_END.exec(match.text) ?? [];\n\n return { from: match.to - name.length, options };\n };\n};\n\n/**\n * The completion source both editors install, with a stable identity.\n *\n * - It keys their extension memo, while callers pass a fresh array on every store push.\n * - CodeMirror asks per request, so it still sees the latest variables.\n */\nexport const useVariableCompletion = (variables: EditorVariable[] = []): CompletionSource =>\n useStableCallback(completeVariables(variables));\n","import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';\nimport type { KeyboardEvent, ReactNode } from 'react';\nimport type { CompletionSource } from '@codemirror/autocomplete';\nimport { autocompletion, completeAnyWord } from '@codemirror/autocomplete';\nimport { unifiedMergeView } from '@codemirror/merge';\nimport { EditorView, keymap, placeholder as cmPlaceholder } from '@codemirror/view';\nimport CodeMirror, {\n EditorState,\n type Extension,\n type ReactCodeMirrorRef,\n} from '@uiw/react-codemirror';\n\nimport { keyCodes } from '../../constants/keyCodes';\nimport { useStableCallback } from '../../hooks/useStableCallback';\nimport { cn } from '../../utils';\nimport { HelpBlock } from '../HelpBlock';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nimport { ButtonToolbar } from './ButtonToolbar';\nimport { buildChromeStyles, buildInputChrome } from './editorChrome';\nimport type { LANGUAGE_MODE } from './helpers';\nimport {\n buildBaseThemeStyles,\n buildBasicSetup,\n buildCustomTheme,\n buildJsonLinter,\n getLanguageMode,\n shouldLintJson,\n} from './helpers';\nimport { searchExtension, updateSearch } from './search';\nimport { ToggleComponentHelp } from './ToggleComponentHelp';\nimport { useThemedExtension } from './tokenTheme';\nimport { useTooltipsExtension } from './tooltips';\nimport { type EditorVariable, useVariableCompletion } from './variableCompletion';\n\ntype Props = {\n value: string;\n previousValue?: string;\n /** `'field'`: `InputGroup` chrome, sized to content (don't pin height). `'plain'`: full-bleed panel. */\n variant?: 'plain' | 'field';\n mode?: LANGUAGE_MODE;\n placeholder?: string;\n /** Screen-reader name: the editor has no visible label of its own. */\n ariaLabel?: string;\n /** Prefer over `ariaLabel` inside a form. */\n ariaLabelledBy?: string;\n ariaDescribedBy?: string;\n /** Visual error styling is the caller's (`variant=\"field\"`). */\n ariaInvalid?: boolean;\n ariaRequired?: boolean;\n /** JSON modes: a blank document is not a parse error. Off by default: the mark explains a disabled Save. */\n allowBlankDocument?: boolean;\n /** Bound on CodeMirror's content node (the wrapper is not what gets focused). */\n onBlur?: () => void;\n /** Highlights matches; the find UI is the caller's. Omit both props to skip the search extension. */\n searchQuery?: string;\n searchMatchIndex?: number;\n readOnly?: boolean;\n /** Refuses edits without changing the look, e.g. during a save; `readOnly` makes a greyed viewer. */\n inputLocked?: boolean;\n /** One word per label (a space breaks matching; phrases go in `completionSource`). Pass a stable array. */\n autocompletions?: string[];\n /** Cursor-dependent completions; wins over `autocompletions` / `completeAny`. Memoize it. */\n completionSource?: CompletionSource;\n /** Completed into `{{name}}`, alongside `completionSource`. */\n variables?: EditorVariable[];\n /** `false` silences every source, the language's own included (e.g. shell mode used only for colours). */\n withCompletions?: boolean;\n extraKeys?: Record<string, () => void>;\n withToggleCommentHint?: boolean;\n withAutofocus?: boolean;\n withLineNumbers?: boolean;\n withLineWrapping?: boolean;\n withCollapseUnchanged?: boolean;\n withCopyButton?: boolean;\n completeAny?: boolean;\n help?: ReactNode;\n helpPostfix?: ReactNode;\n /** Toolbar actions beside the copy button; pass `size=\"icon-xs\"` buttons to fit the 28px chip. */\n renderAdditionalButtons?: (value?: string) => ReactNode;\n className?: string;\n} & (\n | { readOnly: true; onChange?: never }\n // `boolean`, not `false`: a permission-locked field still needs its handler when editable.\n | { readOnly?: boolean; onChange: (value: string) => void }\n);\n\nconst emptyObject = {};\n\nexport const CodeEditor = ({\n value,\n previousValue,\n onChange,\n variant = 'plain',\n mode = 'application/json',\n placeholder = '',\n ariaLabel,\n ariaLabelledBy,\n ariaDescribedBy,\n ariaInvalid,\n ariaRequired,\n allowBlankDocument = false,\n onBlur,\n searchQuery,\n searchMatchIndex,\n readOnly = false,\n inputLocked = false,\n autocompletions,\n completionSource,\n variables,\n withCompletions = true,\n extraKeys = emptyObject,\n withToggleCommentHint = false,\n withAutofocus = false,\n withLineNumbers = true,\n withLineWrapping = true,\n withCollapseUnchanged = false,\n withCopyButton = false,\n completeAny = false,\n help = null,\n helpPostfix = null,\n renderAdditionalButtons,\n className,\n}: Props) => {\n // A new handler identity rebuilds CodeMirror's extension tree; callers pass inline arrows.\n const handleChange = useStableCallback((next: string) => onChange?.(next));\n const handleBlur = useStableCallback(() => onBlur?.());\n\n // Presence, not truthiness, keeps the extension set stable while the query changes.\n const withSearch = searchQuery !== undefined;\n const withBlur = onBlur !== undefined;\n const editorRef = useRef<ReactCodeMirrorRef>(null);\n\n // `null` when empty, so the extension is left out.\n const contentAria = useMemo(() => {\n const attributes: Record<string, string> = {};\n if (ariaLabel !== undefined) attributes['aria-label'] = ariaLabel;\n if (ariaLabelledBy !== undefined) attributes['aria-labelledby'] = ariaLabelledBy;\n if (ariaDescribedBy !== undefined) attributes['aria-describedby'] = ariaDescribedBy;\n // Stringified: `contentAttributes` would drop a boolean `false`.\n if (ariaInvalid !== undefined) attributes['aria-invalid'] = String(ariaInvalid);\n if (ariaRequired !== undefined) attributes['aria-required'] = String(ariaRequired);\n return Object.keys(attributes).length > 0 ? attributes : null;\n }, [ariaLabel, ariaLabelledBy, ariaDescribedBy, ariaInvalid, ariaRequired]);\n\n useEffect(() => {\n const view = editorRef.current?.view;\n if (view && withSearch) updateSearch(view, searchQuery, searchMatchIndex);\n }, [withSearch, searchQuery, searchMatchIndex]);\n\n // A view created with a query already set (remount, tab switch) needs it applied on build.\n const handleCreateEditor = useStableCallback((view: EditorView) => {\n if (searchQuery) updateSearch(view, searchQuery, searchMatchIndex);\n });\n\n // Callers pass this inline; only the key set rebuilds the keymap, handlers are read on press.\n const extraKeysRef = useRef(extraKeys);\n useLayoutEffect(() => {\n extraKeysRef.current = extraKeys;\n });\n\n const boundKeysSignature = Object.keys(extraKeys).join('\\n');\n const boundKeys = useMemo(\n () => boundKeysSignature.split('\\n').filter(Boolean),\n [boundKeysSignature],\n );\n\n const tooltipLayer = useTooltipsExtension();\n\n // Built here, not inside `languageData.of`, which runs per completion request.\n const variableCompletion = useVariableCompletion(variables);\n\n // Key has no component prefix: shared with `SqlEditor`.\n const customTheme = useThemedExtension('editor:syntax', buildCustomTheme);\n\n // The brand is in the cache key: `useThemedExtension` caches per key and tracks only `<html>`.\n const isArgo = useArgoDesign();\n const isField = variant === 'field';\n const baseTheme = useThemedExtension(\n isField ? `code-editor:field:${isArgo ? 'argo' : 'legacy'}` : 'code-editor:chrome',\n (scheme) =>\n // `dark` activates every `&dark` rule (ours and CodeMirror's); set here so swapping the\n // github palette in `buildCustomTheme` cannot turn them off.\n EditorView.theme(\n {\n ...buildBaseThemeStyles(scheme),\n ...(isField ? buildChromeStyles(buildInputChrome(isArgo)) : null),\n },\n { dark: scheme === 'dark' },\n ),\n );\n\n const commonExtensions: Extension[] = useMemo(() => {\n const callerCompletions =\n completionSource ??\n (completeAny ? completeAnyWord : autocompletions?.length ? autocompletions : null);\n\n // An empty list is left out, or CodeMirror runs a never-matching source on every keystroke.\n const completionEntries = [\n ...(callerCompletions ? [{ autocomplete: callerCompletions }] : []),\n { autocomplete: variableCompletion },\n ];\n\n return [\n getLanguageMode(mode),\n shouldLintJson(mode, readOnly) ? buildJsonLinter(allowBlankDocument) : [],\n withLineWrapping ? EditorView.lineWrapping : [],\n EditorState.languageData.of(() => completionEntries),\n keymap.of(\n boundKeys.map((key) => ({\n key,\n run: () => {\n extraKeysRef.current[key]?.();\n return true;\n },\n })),\n ),\n readOnly || !withCompletions\n ? []\n : [\n // The only `autocompletion()` (`buildBasicSetup` disables basicSetup's). Not gated on\n // the completion props, so the language's own vocabulary still completes.\n autocompletion(),\n ],\n // On the focused content node (`div[role=\"textbox\"]`), not the wrapper.\n contentAria ? EditorView.contentAttributes.of(contentAria) : [],\n withBlur ? EditorView.domEventHandlers({ blur: handleBlur }) : [],\n withSearch ? searchExtension() : [],\n tooltipLayer,\n baseTheme,\n ];\n }, [\n autocompletions,\n completionSource,\n variableCompletion,\n completeAny,\n withCompletions,\n boundKeys,\n mode,\n readOnly,\n allowBlankDocument,\n withLineWrapping,\n baseTheme,\n contentAria,\n withBlur,\n handleBlur,\n withSearch,\n tooltipLayer,\n ]);\n\n const extensions = useMemo(() => {\n return [\n ...commonExtensions,\n cmPlaceholder(placeholder),\n EditorView.editable.of(!readOnly),\n // The lock is only this facet: `contenteditable` drives the read-only wash and `basicSetup`\n // holds the undo history, so neither is reconfigured.\n EditorState.readOnly.of(readOnly || inputLocked),\n previousValue\n ? unifiedMergeView({\n original: previousValue,\n mergeControls: false,\n highlightChanges: false,\n collapseUnchanged: withCollapseUnchanged ? {} : undefined,\n })\n : [],\n ];\n }, [commonExtensions, placeholder, readOnly, inputLocked, previousValue, withCollapseUnchanged]);\n\n const config = useMemo(() => {\n return {\n ...buildBasicSetup(readOnly),\n lineNumbers: withLineNumbers,\n // Mod-f would open CodeMirror's own search panel beside the caller's.\n ...(withSearch ? { searchKeymap: false } : null),\n };\n }, [withLineNumbers, readOnly, withSearch]);\n\n return (\n // oxlint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n data-variant={variant}\n className={cn(\n // Scoped to CodeMirror's box so the toolbar needn't undo it with `!important`.\n 'tw:relative tw:flex tw:min-h-0 tw:flex-col tw:[&_.cm-mergeViewEditor]:overflow-visible tw:[&_.cm-mergeViewEditors]:h-full tw:[&_.cm-mergeView]:h-full tw:[&_>.cm-theme]:h-full',\n // Field: transparent so square corners don't show; visible so the focus ring isn't cropped.\n isField\n ? 'tw:[&_>.cm-theme]:overflow-visible tw:[&_>.cm-theme]:bg-transparent'\n : 'tw:[&_>.cm-theme]:overflow-auto tw:[&_>.cm-theme]:bg-background',\n className,\n )}\n onKeyDown={(event: KeyboardEvent) => {\n if (event.key === keyCodes.ESCAPE) {\n event.stopPropagation();\n }\n }}\n >\n <ButtonToolbar value={withCopyButton ? value : undefined}>\n {renderAdditionalButtons?.(value)}\n </ButtonToolbar>\n <CodeMirror\n ref={editorRef}\n onCreateEditor={handleCreateEditor}\n theme={customTheme}\n value={value}\n onChange={handleChange}\n extensions={extensions}\n autoFocus={withAutofocus}\n basicSetup={config}\n />\n {!readOnly && (withToggleCommentHint || help || helpPostfix) && (\n <HelpBlock className=\"tw:mt-2 tw:flex tw:flex-wrap tw:gap-1\">\n {help}\n {withToggleCommentHint ? <ToggleComponentHelp /> : null}\n {helpPostfix}\n </HelpBlock>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAa,iBAAiB,EAAE,OAAO,eAAyD;CAC9F,IAAI,CAAC,SAAS,CAAC,UAAU,OAAO;CAEhC,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACG,CAAC,CAAC,SAAS,oBAAC,iBAAD;GAAiB,MAAK;GAAU,SAAQ;GAAY,MAAM;EAAQ,CAAA,GAC7E,QACE;;AAET;;;ACXA,MAAM,WAAW;CACf;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AACA,MAAM,cAAwC;CAAE,MAAM,CAAC,UAAU;CAAG,QAAQ,CAAC,WAAW;AAAE;AAC1F,MAAM,YAAY;CAAC;CAAY;CAAa;CAAc;CAAW;CAAmB;AAAI;AAG5F,MAAM,YAAY;CAAC;CAAY;CAAa;AAAI;AAChD,MAAM,UAAU;CACd;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AACA,MAAM,QAAQ;CACZ;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAM,kBAAkB,SAAS,SAAS,YAAY;CACpD,MAAM,cAAc,YAAY;CAEhC,OAAO,cAAc,YAAY,KAAK,eAAe,GAAG,QAAQ,GAAG,YAAY,IAAI,CAAC,OAAO;AAC7F,CAAC;AAKD,MAAM,eAAe,SAAmB,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,KAAK,GAAG;AAK9F,MAAM,QAAQ,SAAmB,IAAI,OAAO,WAAW,YAAY,IAAI,EAAE,OAAO,GAAG;AACnF,MAAM,UAAU,SAAmB,IAAI,OAAO,WAAW,YAAY,IAAI,EAAE,IAAI,GAAG;AAKlF,MAAM,OAAO;AAEb,MAAM,aAAa,MAAgB,SACjC,KAAK,KAAK,WAAW;CAAE;CAAO;AAAK,EAAE;AAIvC,MAAM,MAAoB,CAAC;CAAE,OAAO;CAAO,MAAM;AAAU,CAAC;AAC5D,MAAM,kBAAkB,UAAU,UAAU,SAAS;AACrD,MAAM,qBAAmD,OAAO,YAC9D,OAAO,QAAQ,WAAW,CAAC,CAAC,KAAK,CAAC,SAAS,iBAAiB,CAC1D,SACA,UAAU,aAAa,SAAS,CAClC,CAAC,CACH;AACA,MAAM,mBAAmB,UAAU,WAAW,UAAU;AACxD,MAAM,eAAe,UAAU,OAAO,UAAU;AAChD,MAAM,iBAAiB,UAAU,SAAS,UAAU;AAKpD,MAAM,gBAAgB,UAAkC;CACtD,MAAM,CAAC,MAAM,SAAS,GAAG,QAAQ;CAEjC,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,IAAI,KAAK,YAAY,MAAM,OAAO,OAAO,CAAC;CAC1C,IAAI,YAAY,KAAA,GAAW,OAAO;CAElC,MAAM,cAAc,mBAAmB,QAAQ,YAAY;CAC3D,IAAI,eAAe,KAAK,WAAW,GAAG,OAAO;CAK7C,MAAM,eAAe,KAAK,QAAQ,OAAO,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE;CAGlE,OAFkB,iBAAiB,KAAA,KAAa,UAAU,SAAS,aAAa,YAAY,CAAC,IAGzF;EAAC,GAAG;EAAkB,GAAG;EAAc,GAAG;CAAc,IACxD,CAAC,GAAG,kBAAkB,GAAG,YAAY;AAC3C;AAEA,MAAM,YAAY,YAAwD;CACxE,MAAM,QAAQ,QAAQ,YAAY,IAAI;CAItC,IAAI,CAAC,OAAO,QAAQ,CAAC,QAAQ,UAAU,OAAO;CAE9C,MAAM,OAAO,OAAO,QAAQ,QAAQ;CACpC,MAAM,OAAO,QAAQ,MAAM,IAAI,OAAO,IAAI;CAC1C,MAAM,UAAU,aACd,KAAK,KACF,MAAM,GAAG,OAAO,KAAK,IAAI,CAAC,CAC1B,MAAM,KAAK,CAAC,CACZ,OAAO,OAAO,CACnB;CAEA,OAAO,QAAQ,SAAS,IAAI;EAAE;EAAM;EAAS,UAAU;CAAK,IAAI;AAClE;AAEA,MAAa,MAAM,WAAW;CAC5B,cAAc;EAEZ,eAAe;GAAE,MAAM;GAAM,OAAO;IAAE,MAAM;IAAM,OAAO;GAAK;EAAE;EAChE,cAAc;CAChB;CACA,OAAO;EACL;GAAE,OAAO;GAA2B,OAAO;EAAS;EAGpD;GAAE,OAAO;GAAS,OAAO;GAAW,KAAK;EAAK;EAC9C;GAAE,OAAO,KAAK,eAAe;GAAG,OAAO;EAAU;EACjD;GAAE,OAAO,KAAK,SAAS;GAAG,OAAO;EAAe;EAChD;GAAE,OAAO,OAAO,OAAO;GAAG,OAAO;EAAe;EAChD;GAAE,OAAO,OAAO,KAAK;GAAG,OAAO;EAAgB;EAC/C;GAAE,OAAO;GAA6B,OAAO;EAAW;EACxD;GAAE,OAAO;GAAQ,OAAO;EAAS;EACjC;GAAE,OAAO;GAAc,OAAO;EAAO;CACvC;AACF,CAAC;;;;;;;;ACnJD,MAAM,cAAc;AACpB,MAAM,gBAAgB;AACtB,MAAM,kBAAkB;AACxB,MAAM,aAAa;AACnB,MAAM,iBAAiB;AACvB,MAAM,aAAa;AACnB,MAAM,aAAa;AACnB,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,SAAS;AACf,MAAM,iBAAiB;AACvB,MAAM,YAAY;AAClB,MAAM,SAAS;AACf,MAAM,QAAQ;AACd,MAAM,OAAO;AACb,MAAM,SAAS;AACf,MAAM,WAAW;AACjB,MAAM,aAAa;AAEnB,MAAM,WAA+C;CACnD,OAAO;CACP,MAAM;CACN,OAAO;CACP,QAAQ;CACR,UAAU;CACV,IAAI;CACJ,MAAM;CACN,MAAM;CACN,KAAK;CACL,IAAI;CACJ,YAAY;CACZ,OAAO;CACP,MAAM;CACN,OAAO;CACP,MAAM;AACR;AAYA,MAAa,UAA+B;CAC1C,MAAM;CAGN,cAAc,EAAE,eAAe;EAAE,MAAM;EAAM,OAAO;GAAE,MAAM;GAAM,OAAO;EAAK;CAAE,EAAE;CAElF,mBAAmB;EACjB,UAAU;EACV,WAAW;EACX,iBAAiB;EACjB,QAAQ;EACR,cAAc;EACd,cAAc;EACd,WAAW;CACb;CAEA,QAAQ,QAAQ,UAAU;EACxB,IAAI,MAAM,UAAU;GAClB,IAAI,OAAO,MAAM,WAAW,GAAG;IAC7B,MAAM,WAAW;IACjB,OAAO;GACT;GACA,OAAO,KAAK;GACZ,OAAO;EACT;EAGA,IAAI,MAAM,WAAW;GACnB,IAAI,MAAM,mBAAmB,MAAM;IACjC,IAAI,OAAO,MAAM,cAAc,GAAG;KAChC,MAAM,YAAY;KAClB,OAAO;IACT;IACA,MAAM,kBAAkB,OAAO,YAAY;GAC7C;GACA,IAAI,OAAO,YAAY,KAAK,MAAM,iBAAiB;IACjD,OAAO,UAAU;IACjB,OAAO;GACT;GACA,IAAI,OAAO,MAAM,cAAc,GAAG;IAChC,MAAM,YAAY;IAClB,OAAO;GACT;GACA,OAAO,KAAK;GACZ,OAAO;EACT;EAEA,IAAI,MAAM,UAAU,MAAM,cAAc;GACtC,MAAM,QAAQ,MAAM,SAAS,WAAW;GAExC,IAAI,MAAM,WACJ;QAAA,OAAO,MAAM,MAAM,eAAe,aAAa,UAAU,GAAG,OAAO;GAAA,OAClE;IACL,IAAI,OAAO,MAAM,MAAM,GAAG,OAAO;IACjC,IAAI,OAAO,MAAM,cAAc,GAAG,OAAO;IACzC,IAAI,OAAO,MAAM,SAAS,GAAG,OAAO;GACtC;GAEA,IAAI,OAAO,MAAM,MAAM,eAAe,eAAe,YAAY,GAAG;IAClE,MAAM,SAAS;IACf,MAAM,eAAe;IACrB,OAAO;GACT;GAEA,OAAO,KAAK;GACZ,OAAO;EACT;EAEA,IAAI,OAAO,MAAM,aAAa,GAAG;GAC/B,OAAO,UAAU;GACjB,OAAO;EACT;EACA,IAAI,OAAO,MAAM,eAAe,GAAG;GACjC,MAAM,WAAW;GACjB,OAAO;EACT;EAEA,MAAM,WAAW,OAAO,MAAM,MAAM;EACpC,IAAI,MAAM,QAAQ,QAAQ,GAAG;GAC3B,MAAM,eAAe;GACrB,MAAM,YAAY,SAAS,OAAO;GAClC,MAAM,eAAe,SAAS,OAAO;GACrC,OAAO;EACT;EAEA,MAAM,SAAS,OAAO,MAAM,KAAK;EACjC,IAAI,MAAM,QAAQ,MAAM,GAAG;GACzB,MAAM,SAAS;GACf,MAAM,YAAY,OAAO,OAAO;GAChC,MAAM,eAAe,OAAO,OAAO;GACnC,OAAO;EACT;EAEA,IAAI,OAAO,MAAM,UAAU,GAAG;GAC5B,MAAM,YAAY;GAClB,MAAM,kBAAkB;GACxB,OAAO;EACT;EAEA,IAAI,OAAO,MAAM,IAAI,GAAG,OAAO;EAC/B,IAAI,OAAO,MAAM,MAAM,GAAG,OAAO;EACjC,IAAI,OAAO,MAAM,QAAQ,GAAG,OAAO;EAGnC,MAAM,aAAa,OAAO,MAAM,UAAU;EAC1C,IAAI,MAAM,QAAQ,UAAU,GAAG,OAAO,SAAS,WAAW,OAAO;EAEjE,OAAO,KAAK;EACZ,OAAO;CACT;AACF;AC5JA,MAAM,oBAAoB;;;;;;;AAQ1B,MAAa,iBAAiB,WAAgC;CAC5D,MAAM,OAAO,WAAW;CAExB,OAAO;EACL,OAAO,KAAa,WAAoB,OAAO,GAAG,UAA0B;EAC5E,SAAS,KAAa,WAAoB,OAAO,GAAG,MAAM,sBAAsB;CAClF;AACF;;;;;;;;;;ACXA,MAAa,sBAAsB,QAA6B,eAAuB;CACrF,MAAM,OAAO,WAAW;CAExB,OAAO;EAEL;GAAE,KAAK;IAAC,KAAK;IAAM,KAAK,QAAQ,KAAK,MAAM;IAAG,KAAK;GAAO;GAAG,OAAO;EAAW;EAE/E;GAAE,KAAK,KAAK,SAAS,KAAK,IAAI;GAAG,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO,OAAO;EAAK;EAEvF;GAAE,KAAK,KAAK,QAAQ,KAAK,IAAI;GAAG,OAAO,OAAO,OAAO,KAAK,OAAO,OAAO,KAAK;EAAK;EAElF;GAAE,KAAK,KAAK;GAAQ,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,QAAQ;EAAK;EAE5E,GAAI,OACA,CAAC,IACD;GAEE;IAAE,KAAK;KAAC,KAAK;KAAS,KAAK;KAAU,KAAK;IAAY;IAAG,OAAO,OAAO,MAAM;GAAK;GAElF;IAAE,KAAK,KAAK;IAAS,OAAO,OAAO,QAAQ;GAAK;GAEhD;IAAE,KAAK,KAAK;IAAO,OAAO,OAAO,MAAM;GAAK;GAE5C;IAAE,KAAK,KAAK;IAAS,OAAO,OAAO,MAAM;GAAK;EAChD;EAEJ,GAAI,OAAO,CAAC;GAAE,KAAK;IAAC,KAAK;IAAQ,KAAK;IAAK,KAAK;GAAI;GAAG,OAAO,OAAO,KAAK;EAAK,CAAC,IAAI,CAAC;CACvF;AACF;;;AChBA,MAAa,iBAAiB;CAC5B;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,kBAAkB,SAC5B,eAAqC,SAAS,IAAI;AAIrD,MAAa,mBAAmB;AAChC,MAAa,kBAAkB;;;;;;;;;AAU/B,MAAa,wBAAwB,WAAgC;CACnE,MAAM,EAAE,MAAM,WAAW,cAAc,MAAM;CAC7C,MAAM,OAAO,WAAW;CAExB,OAAO;EACL,KAAK,EAAE,YAAY,OAAO;EAC1B,gBAAgB;GACd,iBAAiB,aAAa,WAAW,YAAY;GACrD,OAAO,GAAG,aAAa,sBAAsB,aAAa,EAAE;EAC9D;GAGC,mBAAmB,EAClB,iBAAiB,8BACf,OAAO,aAAa,SAAS,UAAU,IAAI,aAAa,aAAa,aAAa,EACnF,GACH;GACC,GAAG,iBAAiB,gBAAgB,EACnC,iBAAiB,8BAA8B,aAAa,UAAU,aAAa,EAAE,GACvF;EACA,4BAA4B,EAAE,gBAAgB,OAAO;EACrD,yCAAyC;GACvC,WAAW;GACX,UAAU;GACV,YAAY;GACZ,SAAS;EACX;EACA,4BAA4B,EAAE,SAAS,kBAAkB;EACzD,6BAA6B;GAAE,aAAa;GAAQ,cAAc;EAAM;EACxE,eAAe,EAAE,QAAQ,OAAO;EAGhC,2CAAyC,EACvC,iBAAiB,KAAK,OAAO,MAAM,MAAM,OAAO,MAAM,IAAI,EAC5D;EACA,2CAAyC,EACvC,iBAAiB,KAAK,OAAO,MAAM,MAAM,OAAO,MAAM,IAAI,EAC5D;EACA,iDAA+C,EAC7C,iBAAiB,OAAO,OAAO,MAAM,MAAM,OAAO,MAAM,IAAI,EAC9D;EACA,iDAA+C,EAC7C,iBAAiB,OAAO,OAAO,MAAM,MAAM,OAAO,MAAM,IAAI,EAC9D;EACA,2CAAyC,EACvC,YAAY,OAAO,OAAO,MAAM,MAAM,OAAO,MAAM,IAAI,EACzD;EACA,2CAAyC,EACvC,YAAY,OAAO,OAAO,MAAM,MAAM,OAAO,MAAM,IAAI,EACzD;EAEA,2BAAyB,EACvB,iBAAiB,GAAG,aAAa,cAAc,aAAa,EAAE,aAChE;EACA,uCAAqC,EACnC,iBAAiB,GAAG,aAAa,SAAS,aAAa,EAAE,aAC3D;EACA,oBAAoB;GAAE,UAAU;GAAY,QAAQ;GAAI,OAAO;GAAQ,aAAa;EAAE;EACtF,sHACE,EAAE,aAAa,EAAE;CACrB;AACF;AAIA,MAAM,aAAa;CACjB,gBAAgB;CAChB,eAAe;CACf,YAAY;CACZ,YAAY;CACZ,qBAAqB;CACrB,2BAA2B;AAC7B;AAKA,MAAa,mBAAmB,cAA0C;CACxE,GAAG;CACH,GAAI,WACA;EACE,eAAe;EACf,qBAAqB;EACrB,YAAY;EACZ,eAAe;EACf,sBAAsB;EACtB,YAAY;EACZ,2BAA2B;CAC7B,IACA;AACN;;;;;;;;AASA,MAAa,oBAAoB,WAAgC;CAC/D,MAAM,aAAa,aAAa,cAAc,UAAU;CAGxD,QAFa,WAAW,SAAS,iBAAiB,gBAAA,CAEtC;EACV,UAAU;GACR,YAAY;GACZ,YAAY,aAAa,cAAc,aAAa;GACpD;GACA,OAAO;GACP,kBAAkB,aAAa,SAAS,aAAa;GACrD,kBAAkB,aAAa,oBAAoB,aAAa;GAChE,cAAc;GACd,eAAe;GACf,WAAW,aAAa,WAAW,YAAY;GAC/C,gBAAgB,aAAa,WAAW,cAAc,EAAG;EAC3D;EACA,QAAQ,mBAAmB,QAAQ,UAAU;CAC/C,CAAC;AACH;AAEA,MAAa,mBAAmB,SAAyB;CACvD,QAAQ,MAAR;EACE,KAAK,KAAA;EACL,KAAK,oBACH,OAAO,KAAK;EACd,KAAK,iBACH,OAAO,OAAO;EAChB,KAAK,cACH,OAAO,sBAAsB,WAAW;EAC1C,KAAK,gBACH,OAAO,sBAAsB,KAAK;EACpC,KAAK,gBACH,OAAO,sBAAsB,UAAU;EACzC,KAAK,gBACH,OAAO,sBAAsB,KAAK;EACpC,KAAK,gBACH,OAAO,sBAAsB,WAAW;EAC1C,KAAK,gBACH,OAAO,sBAAsB,UAAU;EACzC,KAAK,gBACH,OAAO,sBAAsB,KAAK;EACpC,KAAK,eACH,OAAO,eAAe,OAAO,CAAC;EAChC,KAAK,aACH,OAAO,eAAe,OAAO,KAAK;EACpC,KAAK,eACH,OAAO,eAAe,OAAO,IAAI;EACnC,KAAK,gBACH,OAAO,eAAe,OAAO,OAAO;EACtC,KAAK,cACH,OAAO,eAAe,OAAO,GAAG;EAClC,KAAK,mBACH,OAAO,WAAW,EAAE,KAAK,KAAK,CAAC;EACjC,KAAK,mBACH,OAAO,WAAW;GAAE,KAAK;GAAM,YAAY;EAAK,CAAC;EAEnD,SACE,OAAO,CAAC;CACZ;AACF;AAGA,MAAa,kBAAkB,MAAiC,aAC9D,SAAS,sBAAsB,CAAC;;;;;;AAOlC,MAAa,qBACV,YACA,SACC,KAAK,MAAM,IAAI,SAAS,CAAC,CAAC,KAAK,MAAM,KAAK,CAAC,IAAI,OAAO,IAAI;;;;;;;AAQ9D,MAAa,mBAAmB,uBAAgC;CAC9D,MAAM,SAAS,gBAAgB;CAE/B,OAAO,OAAO,qBAAqB,kBAAkB,MAAM,IAAI,MAAM;AACvE;;;;;;;;;;AC9NA,MAAa,oBAAoB,WAAkC;CACjE,OAAO;EACL,SAAS,SACL,aAAa,SAAS,aAAa,IACnC,aAAa,aAAa,aAAa;EAC3C,aAAa,SACT,aAAa,SAAS,aAAa,IACnC,aAAa,aAAa,aAAa;EAC3C,iBAAiB,aAAa,SAAS,aAAa;EACpD,qBAAqB,aAAa,SAAS,aAAa;EACxD,kBAAkB;EAClB,kBAAkB,SACd,aAAa,WAAW,WAAW,IACnC,aAAa,QAAQ,YAAY;EACrC,WAAW,aAAa,aAAa,QAAQ,cAAc,SAAS,KAAM,EAAG;EAC7E,QAAQ,SAAS,8BAA8B;EAG/C,UAAU,SAAS,QAAQ;EAE3B,UAAU;GAAE,MAAM;GAAQ,OAAO;EAAO;CAC1C;AACF;;AAGA,MAAa,2BAAyC;CACpD,SAAS,aAAa,QAAQ,aAAa;CAC3C,aAAa;CACb,iBAAiB,aAAa,SAAS,aAAa;CACpD,qBAAqB;CACrB,kBAAkB,aAAa,QAAQ,YAAY;CACnD,kBAAkB,aAAa,QAAQ,YAAY;CACnD,WAAW,aAAa,aAAa,QAAQ,cAAc,EAAG;CAC9D,QAAQ;CACR,UAAU;CACV,UAAU;AACZ;;AAGA,MAAa,qBAAqB,YAA0B;CAC1D,eAAe;EACb,QAAQ,aAAa,OAAO;EAC5B,cAAc,OAAO;EACrB,iBAAiB,OAAO;EACxB,YAAY,OAAO;EACnB,eAAe,OAAO;CACxB;CACA,6CAA6C,EAAE,iBAAiB,OAAO,QAAQ;CAE/E,GAAI,OAAO,WACP,EAEE,kDAAkD;EAChD,aAAa,OAAO,SAAS;EAC7B,cAAc,OAAO,SAAS;CAChC,EACF,IACA;CAEJ,GAAI,OAAO,mBACP,GAAG,GAAG,gBAAgB,UAAU,EAAE,aAAa,OAAO,iBAAiB,EAAE,IACzE;EACH,GAAG,gBAAgB,iBAAiB;EACnC,aAAa,OAAO;EACpB,WAAW,OAAO;CACpB;EAEC,mBAAmB;EAClB,iBAAiB,OAAO;EACxB,aAAa,OAAO;CACtB;EACC,GAAG,iBAAiB,gBAAgB,EAAE,iBAAiB,OAAO,gBAAgB;EAC9E,GAAG,iBAAiB,iBAAiB,EAAE,iBAAiB,OAAO,gBAAgB;AAClF;;;AC/EA,MAAM,kBAAkB,YAAY,OAGjC;AASH,SAAS,YAAY,KAAW,OAA8B;CAE5D,IAAI,CAAC,SAAS,MAAM,SAAS,IAAI,QAAQ,OAAO,CAAC;CAEjD,OAAO,mBAAmB,IAAI,SAAS,GAAG,KAAK,CAAC,CAAC,KAAK,MAAM,WAAW;EACrE;EACA,IAAI,OAAO,MAAM;EACjB,YAAY;CACd,EAAE;AACJ;AAEA,SAAS,kBAAkB,SAAwB,oBAA4C;CAC7F,MAAM,cAAc,QAAQ,KAAK,UAAU;EACzC,MAAM,aAAa,MAAM,eAAe;EAMxC,OAJmB,WAAW,KAAK,EACjC,OAAO,aAAa,4BAA4B,iBAClD,CAEgB,CAAC,CAAC,MAAM,MAAM,MAAM,MAAM,EAAE;CAC9C,CAAC;CAED,OAAO,WAAW,IAAI,aAAa,IAAI;AACzC;AAEA,MAAM,cAAc,WAAW,OAAoB;CACjD,SAAS;EACP,OAAO;GACL,OAAO;GACP,oBAAoB,KAAA;GACpB,SAAS,CAAC;GACV,aAAa,WAAW;EAC1B;CACF;CAEA,OAAO,OAAO,IAAI;EAChB,IAAI,WAAW;EAEf,KAAK,MAAM,UAAU,GAAG,SAAS;GAC/B,IAAI,CAAC,OAAO,GAAG,eAAe,GAC5B;GAGF,MAAM,EAAE,OAAO,uBAAuB,OAAO;GAE7C,MAAM,UAAU,YAAY,GAAG,MAAM,KAAK,KAAK;GAI/C,WAAW;IACT;IACA;IACA;IACA,aANkB,kBAAkB,SAAS,kBAMnC;GACZ;EACF;EAEA,IAAI,GAAG,cAAc,SAAS,OAAO;GACnC,MAAM,UAAU,YAAY,GAAG,MAAM,KAAK,SAAS,KAAK;GACxD,MAAM,cAAc,kBAAkB,SAAS,SAAS,kBAAkB;GAE1E,WAAW;IACT,GAAG;IACH;IACA;GACF;EACF;EAEA,OAAO;CACT;CAEA,UAAU,UAAU,WAAW,YAAY,KAAK,QAAQ,UAAU,MAAM,WAAW;AACrF,CAAC;AAED,MAAM,mBAAmB,WAAW,UAClC,MAAM;CACJ;CAEA,OAAO,QAAoB;EACzB,MAAM,QAAQ,OAAO,MAAM,MAAM,WAAW;EAE5C,IACE,MAAM,uBAAuB,KAAA,KAC7B,MAAM,uBAAuB,KAAK,mBAClC;GACA,MAAM,QAAQ,MAAM,QAAQ,MAAM;GAElC,IAAI,OACF,4BAA4B;IAC1B,OAAO,KAAK,SAAS,EACnB,SAAS,WAAW,eAAe,MAAM,MAAM,EAAE,GAAG,SAAS,CAAC,EAChE,CAAC;GACH,CAAC;GAGH,KAAK,oBAAoB,MAAM;EACjC;EAEA,IAAI,MAAM,uBAAuB,KAAA,GAC/B,KAAK,oBAAoB,KAAA;CAE7B;AACF,CACF;;;;;;;AAQA,MAAM,cAAc,WAAW,UAAU;CACvC,mBAAmB,EACjB,iBAAiB,OAAO,KAAK,KAC/B;CACA,0BAA0B,EACxB,OAAO,GAAG,OAAO,KAAK,KAAK,aAC7B;CACA,4BAA4B,EAC1B,iBAAiB,OAAO,KAAK,KAC/B;CACA,mCAAmC,EACjC,OAAO,GAAG,OAAO,MAAM,aACzB;CAEA,yBAAyB,EACvB,iBAAiB,GAAG,OAAO,KAAK,SAClC;CACA,gCAAgC,EAC9B,OAAO,GAAG,OAAO,KAAK,KAAK,aAC7B;CACA,kCAAkC,EAChC,iBAAiB,OAAO,KAAK,KAC/B;CACA,yCAAyC,EACvC,OAAO,GAAG,OAAO,QAAQ,KAAK,aAChC;AACF,CAAC;AAED,SAAgB,kBAAkB;CAChC,OAAO;EAAC;EAAa;EAAkB;CAAW;AACpD;AAEA,SAAgB,aAAa,MAAkB,OAAe,oBAA6B;CACzF,KAAK,SAAS,EAAE,SAAS,gBAAgB,GAAG;EAAE;EAAO;CAAmB,CAAC,EAAE,CAAC;AAC9E;;;AC/KA,MAAa,4BACX,qBAAC,OAAD,EAAA,UAAA;CAAK;CACC,oBAAC,KAAD,EAAA,UAAM,QAAQ,cAAc,SAAc,CAAA;CAAC;AAC5C,EAAA,CAAA;;;ACCP,MAAM,6BAAa,IAAI,IAAuB;;;;;;;;AAS9C,MAAa,sBACX,UACA,UACc;CACd,MAAM,EAAE,QAAQ,UAAU,aAAa,mBAAmB;CAC1D,MAAM,MAAM,GAAG,SAAS,GAAG;CAG3B,IAAI,SAAS,WAAW,IAAI,GAAG;CAC/B,IAAI,CAAC,QAAQ;EACX,SAAS,MAAM,MAAM;EACrB,WAAW,IAAI,KAAK,MAAM;CAC5B;CAEA,OAAO;AACT;;;ACxBA,MAAM,mCAAmC,UACvC,MAAM,cAAc,UACpB,MAAM,cAAc,UACpB,MAAM,WAAW,UACjB,MAAM,UAAU,UAChB,MAAM,gBAAgB,UACtB,MAAM,WAAW,UACjB,MAAM,mBAAmB,UACzB,oCAAoC,KAAK,MAAM,OAAO,KACtD,6CAA6C,KAAK,MAAM,UAAU;AAIpE,MAAM,SAAS,UACb,MAAM,cAAc,aACpB,MAAM,cAAc,aACpB,MAAM,cAAc,UACpB,MAAM,sBAAsB,aAC5B,6BAA6B,KAAK,MAAM,OAAO;;;;;;;;AASjD,MAAM,mBAAmB,SAAsB;CAC7C,IAAI,mBAAuC;CAE3C,KAAK,IAAI,OAAO,KAAK,eAAe,QAAQ,SAAS,SAAS,MAAM,OAAO,KAAK,eAAe;EAC7F,MAAM,QAAQ,iBAAiB,IAAI;EAEnC,IAAI,MAAM,KAAK,GACb,mBAAmB;OACd,IAAI,gCAAgC,KAAK,GAC9C,OAAO,kBAAkB,iBAAiB;CAE9C;CAEA,OAAO,kBAAkB,iBAAiB;AAC5C;;;;;;;;AASA,MAAM,0BAAqC;CAEzC,MAAM,QAAQ,IAAI,YAAY;CAE9B,OAAO,CACL,MAAM,GAAG,SAAS,CAAC,GACnB,WAAW,QAAQ,SAAS;EAG1B,MAAM,YAAY,iBAAiB;GACjC,IAAI,CAAC,KAAK,IAAI,aAAa;GAE3B,MAAM,SAAS,gBAAgB,KAAK,GAAG;GACvC,IAAI,QAAQ,KAAK,SAAS,EAAE,SAAS,MAAM,YAAY,SAAS,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;EAChF,CAAC;EAED,OAAO,EAAE,eAAe,aAAa,SAAS,EAAE;CAClD,CAAC,CACH;AACF;;;;AAKA,MAAa,6BAA6B,QAAQ,mBAAmB,CAAC,CAAC;;;AC1EvE,MAAM,QAAQ;AAId,MAAM,OAAO,OAAO,GAAG;AACvB,MAAM,WAAW,IAAI,OAAO,OAAO,GAAG,iBAAiB,KAAK,EAAE;AAC9D,MAAM,cAAc,IAAI,OAAO,GAAG,KAAK,EAAE;AACzC,MAAM,UAAU;AAChB,MAAM,UAAU;;;;AAKhB,MAAa,qBAAqB,YAA8B,CAAC,MAAwB;CACvF,IAAI,UAAU,WAAW,GAAG,aAAa;CAEzC,MAAM,UAAwB,UAAU,KAAK,EAAE,MAAM,aAAa;EAEhE,OAAO;EACP,cAAc,KAAK,KAAK;EACxB,QAAQ;EACR,MAAM;EACN,OAAO;EACP,QAAQ,MAAM,YAAY,MAAM,OAAO;GACrC,MAAM,EAAE,QAAQ,KAAK;GACrB,MAAM,OAAO,IAAI,OAAO,IAAI;GAC5B,MAAM,SAAS,KAAK,WAAW,MAAM;GAGrC,MAAM,UAAU,QAAQ,KAAK,IAAI,YAAY,KAAK,MAAM,IAAI,CAAC;GAC7D,MAAM,UAAU,QAAQ,KAAK,IAAI,YAAY,IAAI,KAAK,EAAE,CAAC;GACzD,MAAM,QAAQ,UAAU,OAAO,QAAQ,EAAE,CAAC,SAAS;GACnD,MAAM,MAAM,UAAU,KAAK,QAAQ,EAAE,CAAC,SAAS;GAE/C,KAAK,SAAS;IACZ,SAAS;KAAE,MAAM;KAAO,IAAI;KAAK;IAAO;IACxC,WAAW,EAAE,QAAQ,QAAQ,OAAO,OAAO;GAC7C,CAAC;EACH;CACF,EAAE;CAEF,QAAQ,YAA+B;EACrC,MAAM,QAAQ,QAAQ,YAAY,QAAQ;EAE1C,IAAI,CAAC,OAAO,MAAM,OAAO;EAEzB,MAAM,CAAC,OAAO,MAAM,YAAY,KAAK,MAAM,IAAI,KAAK,CAAC;EAErD,OAAO;GAAE,MAAM,MAAM,KAAK,KAAK;GAAQ;EAAQ;CACjD;AACF;;;;;;;AAQA,MAAa,yBAAyB,YAA8B,CAAC,MACnE,kBAAkB,kBAAkB,SAAS,CAAC;;;ACqBhD,MAAM,cAAc,CAAC;AAErB,MAAa,cAAc,EACzB,OACA,eACA,UACA,UAAU,SACV,OAAO,oBACP,aAAA,gBAAc,IACd,WACA,gBACA,iBACA,aACA,cACA,qBAAqB,OACrB,QACA,aACA,kBACA,WAAW,OACX,cAAc,OACd,iBACA,kBACA,WACA,kBAAkB,MAClB,YAAY,aACZ,wBAAwB,OACxB,gBAAgB,OAChB,kBAAkB,MAClB,mBAAmB,MACnB,wBAAwB,OACxB,iBAAiB,OACjB,cAAc,OACd,OAAO,MACP,cAAc,MACd,yBACA,gBACW;CAEX,MAAM,eAAe,mBAAmB,SAAiB,WAAW,IAAI,CAAC;CACzE,MAAM,aAAa,wBAAwB,SAAS,CAAC;CAGrD,MAAM,aAAa,gBAAgB,KAAA;CACnC,MAAM,WAAW,WAAW,KAAA;CAC5B,MAAM,YAAY,OAA2B,IAAI;CAGjD,MAAM,cAAc,cAAc;EAChC,MAAM,aAAqC,CAAC;EAC5C,IAAI,cAAc,KAAA,GAAW,WAAW,gBAAgB;EACxD,IAAI,mBAAmB,KAAA,GAAW,WAAW,qBAAqB;EAClE,IAAI,oBAAoB,KAAA,GAAW,WAAW,sBAAsB;EAEpE,IAAI,gBAAgB,KAAA,GAAW,WAAW,kBAAkB,OAAO,WAAW;EAC9E,IAAI,iBAAiB,KAAA,GAAW,WAAW,mBAAmB,OAAO,YAAY;EACjF,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,IAAI,aAAa;CAC3D,GAAG;EAAC;EAAW;EAAgB;EAAiB;EAAa;CAAY,CAAC;CAE1E,gBAAgB;EACd,MAAM,OAAO,UAAU,SAAS;EAChC,IAAI,QAAQ,YAAY,aAAa,MAAM,aAAa,gBAAgB;CAC1E,GAAG;EAAC;EAAY;EAAa;CAAgB,CAAC;CAG9C,MAAM,qBAAqB,mBAAmB,SAAqB;EACjE,IAAI,aAAa,aAAa,MAAM,aAAa,gBAAgB;CACnE,CAAC;CAGD,MAAM,eAAe,OAAO,SAAS;CACrC,sBAAsB;EACpB,aAAa,UAAU;CACzB,CAAC;CAED,MAAM,qBAAqB,OAAO,KAAK,SAAS,CAAC,CAAC,KAAK,IAAI;CAC3D,MAAM,YAAY,cACV,mBAAmB,MAAM,IAAI,CAAC,CAAC,OAAO,OAAO,GACnD,CAAC,kBAAkB,CACrB;CAEA,MAAM,eAAe,qBAAqB;CAG1C,MAAM,qBAAqB,sBAAsB,SAAS;CAG1D,MAAM,cAAc,mBAAmB,iBAAiB,gBAAgB;CAGxE,MAAM,SAAS,cAAc;CAC7B,MAAM,UAAU,YAAY;CAC5B,MAAM,YAAY,mBAChB,UAAU,qBAAqB,SAAS,SAAS,aAAa,uBAC7D,WAGC,WAAW,MACT;EACE,GAAG,qBAAqB,MAAM;EAC9B,GAAI,UAAU,kBAAkB,iBAAiB,MAAM,CAAC,IAAI;CAC9D,GACA,EAAE,MAAM,WAAW,OAAO,CAC5B,CACJ;CAEA,MAAM,mBAAgC,cAAc;EAClD,MAAM,oBACJ,qBACC,cAAc,kBAAkB,iBAAiB,SAAS,kBAAkB;EAG/E,MAAM,oBAAoB,CACxB,GAAI,oBAAoB,CAAC,EAAE,cAAc,kBAAkB,CAAC,IAAI,CAAC,GACjE,EAAE,cAAc,mBAAmB,CACrC;EAEA,OAAO;GACL,gBAAgB,IAAI;GACpB,eAAe,MAAM,QAAQ,IAAI,gBAAgB,kBAAkB,IAAI,CAAC;GACxE,mBAAmB,WAAW,eAAe,CAAC;GAC9C,YAAY,aAAa,SAAS,iBAAiB;GACnD,OAAO,GACL,UAAU,KAAK,SAAS;IACtB;IACA,WAAW;KACT,aAAa,QAAQ,IAAI,GAAG;KAC5B,OAAO;IACT;GACF,EAAE,CACJ;GACA,YAAY,CAAC,kBACT,CAAC,IACD,CAGE,eAAe,CACjB;GAEJ,cAAc,WAAW,kBAAkB,GAAG,WAAW,IAAI,CAAC;GAC9D,WAAW,WAAW,iBAAiB,EAAE,MAAM,WAAW,CAAC,IAAI,CAAC;GAChE,aAAa,gBAAgB,IAAI,CAAC;GAClC;GACA;EACF;CACF,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,aAAa,cAAc;EAC/B,OAAO;GACL,GAAG;GACHA,YAAcC,aAAW;GACzB,WAAW,SAAS,GAAG,CAAC,QAAQ;GAGhC,YAAY,SAAS,GAAG,YAAY,WAAW;GAC/C,gBACI,iBAAiB;IACf,UAAU;IACV,eAAe;IACf,kBAAkB;IAClB,mBAAmB,wBAAwB,CAAC,IAAI,KAAA;GAClD,CAAC,IACD,CAAC;EACP;CACF,GAAG;EAAC;EAAkBA;EAAa;EAAU;EAAa;EAAe;CAAqB,CAAC;CAE/F,MAAM,SAAS,cAAc;EAC3B,OAAO;GACL,GAAG,gBAAgB,QAAQ;GAC3B,aAAa;GAEb,GAAI,aAAa,EAAE,cAAc,MAAM,IAAI;EAC7C;CACF,GAAG;EAAC;EAAiB;EAAU;CAAU,CAAC;CAE1C,OAEE,qBAAC,OAAD;EACE,gBAAc;EACd,WAAW,GAET,kLAEA,UACI,wEACA,mEACJ,SACF;EACA,YAAY,UAAyB;GACnC,IAAI,MAAM,QAAQ,SAAS,QACzB,MAAM,gBAAgB;EAE1B;EAfF,UAAA;GAiBE,oBAAC,eAAD;IAAe,OAAO,iBAAiB,QAAQ,KAAA;IAC5C,UAAA,0BAA0B,KAAK;GACnB,CAAA;GACf,oBAAC,YAAD;IACE,KAAK;IACL,gBAAgB;IAChB,OAAO;IACA;IACP,UAAU;IACE;IACZ,WAAW;IACX,YAAY;GACb,CAAA;GACA,CAAC,aAAa,yBAAyB,QAAQ,gBAC9C,qBAAC,WAAD;IAAW,WAAU;IAArB,UAAA;KACG;KACA,wBAAwB,oBAAC,qBAAD,CAAsB,CAAA,IAAI;KAClD;IACQ;;EAEV;;AAET"}
1
+ {"version":3,"file":"CodeEditor-Df7VVx08.js","names":["cmPlaceholder","placeholder"],"sources":["../src/components/CodeEditor/ButtonToolbar.tsx","../src/components/CodeEditor/modes/dbt.ts","../src/components/CodeEditor/modes/jsonnet.ts","../src/components/CodeEditor/diffWash.ts","../src/components/CodeEditor/syntaxPalette.ts","../src/components/CodeEditor/helpers.ts","../src/components/CodeEditor/editorChrome.ts","../src/components/CodeEditor/search.ts","../src/components/CodeEditor/ToggleComponentHelp.tsx","../src/components/CodeEditor/tokenTheme.ts","../src/components/CodeEditor/tooltips.ts","../src/components/CodeEditor/variableCompletion.ts","../src/components/CodeEditor/CodeEditor.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\n\nimport { ClipboardButton } from '../../blocks/ClipboardButton';\n\n// Floats over the top-right corner of the editor it is rendered into — private to\n// `CodeEditor`, which is the `relative` ancestor it positions against. `right-3`\n// leaves room for the scrollbar track, whose width the browser owns and no token\n// here describes.\nexport const ButtonToolbar = ({ value, children }: { value?: string; children?: ReactNode }) => {\n if (!value && !children) return null;\n\n return (\n <div className=\"tw:absolute tw:right-3 tw:top-1 tw:z-10 tw:flex tw:gap-0.5 tw:overflow-visible tw:rounded tw:border tw:border-solid tw:border-border tw:!bg-background tw:p-px tw:shadow-sm\">\n {!!value && <ClipboardButton size=\"icon-xs\" variant=\"invisible\" text={value} />}\n {children}\n </div>\n );\n};\n","import type { Completion, CompletionContext, CompletionResult } from '@codemirror/autocomplete';\nimport { simpleMode } from '@codemirror/legacy-modes/mode/simple-mode';\n\n// A dbt step is `dbt <command> [<subcommand>] [arguments, flags and selectors]`,\n// and the vocabulary below is grouped by the slot it belongs to — both to colour\n// it and to decide what is worth offering where.\nconst COMMANDS = [\n 'run-operation',\n 'run',\n 'test',\n 'seed',\n 'snapshot',\n 'list',\n 'ls',\n 'compile',\n 'build',\n 'deps',\n 'docs',\n 'source',\n];\nconst SUBCOMMANDS: Record<string, string[]> = { docs: ['generate'], source: ['freshness'] };\nconst ARGUMENTS = ['--select', '--exclude', '--selector', '--defer', '--resource-type', '-s'];\n// The arguments whose value is a graph selector, and so the only ones a selector\n// method has anything to attach to.\nconst SELECTORS = ['--select', '--exclude', '-s'];\nconst METHODS = [\n 'path:',\n 'source:',\n 'tag:',\n 'package:',\n 'config:',\n 'test_type:',\n 'test_name:',\n 'state:',\n 'exposure:',\n 'metric:',\n 'result:',\n 'source_status:',\n 'column_name:',\n];\nconst FLAGS = [\n '--fail-fast',\n '--warn-error',\n '--favor-state',\n '--vars',\n '--models',\n '--threads',\n '--profiles-dir',\n '--profile',\n '--full-refresh',\n];\n\n// A subcommand only ever highlights together with its command, so `dbt docs` stays\n// unpainted until `generate` follows it.\nconst COMMAND_PHRASES = COMMANDS.flatMap((command) => {\n const subcommands = SUBCOMMANDS[command];\n\n return subcommands ? subcommands.map((subcommand) => `${command} ${subcommand}`) : [command];\n});\n\n// Alternation is first-match, so a word that prefixes another has to come first\n// (`run-operation` before `run`, `--profiles-dir` before `--profile`). Sorting by\n// length keeps that true however the lists above are written.\nconst alternation = (list: string[]) => [...list].sort((a, b) => b.length - a.length).join('|');\n\n// Every keyword follows whitespace, so the leading run is part of the match.\n// Commands and arguments end on a word boundary; methods and flags carry their\n// own terminator (`:`) or need none.\nconst word = (list: string[]) => new RegExp(`^\\\\s+(?:${alternation(list)})\\\\b`, 'i');\nconst prefix = (list: string[]) => new RegExp(`^\\\\s+(?:${alternation(list)})`, 'i');\n\n// The word being completed: letters, digits, `_`, `-` and the `:` a selector\n// method ends with. Whitespace stays out of it, so a two-word label like `docs\n// generate` cannot stretch the match back across the words before the cursor.\nconst WORD = /[\\w:-]*$/;\n\nconst asOptions = (list: string[], type: string): Completion[] =>\n list.map((label) => ({ label, type }));\n\n// `type` drives the popup icon, so each group carries the one that matches the\n// colour the mode paints it in.\nconst DBT: Completion[] = [{ label: 'dbt', type: 'keyword' }];\nconst COMMAND_OPTIONS = asOptions(COMMANDS, 'keyword');\nconst SUBCOMMAND_OPTIONS: Record<string, Completion[]> = Object.fromEntries(\n Object.entries(SUBCOMMANDS).map(([command, subcommands]) => [\n command,\n asOptions(subcommands, 'keyword'),\n ]),\n);\nconst ARGUMENT_OPTIONS = asOptions(ARGUMENTS, 'variable');\nconst FLAG_OPTIONS = asOptions(FLAGS, 'constant');\nconst METHOD_OPTIONS = asOptions(METHODS, 'property');\n\n// Which slice of the vocabulary the cursor's slot can hold, given the words\n// already finished ahead of it. Offering the whole vocabulary everywhere proposes\n// `dbt` mid-command and a selector method with no selector to attach to.\nconst optionsAfter = (words: string[]): Completion[] => {\n const [step, command, ...rest] = words;\n\n if (step === undefined) return DBT;\n if (step.toLowerCase() !== 'dbt') return [];\n if (command === undefined) return COMMAND_OPTIONS;\n\n const subcommands = SUBCOMMAND_OPTIONS[command.toLowerCase()];\n if (subcommands && rest.length === 0) return subcommands;\n\n // A selector argument takes any number of space-separated values, so what\n // decides the slot is the last argument, not whether a selector appeared at all:\n // `--select tag:a tag:b` keeps offering methods, `--select a --profile p` stops.\n const lastArgument = rest.filter((it) => it.startsWith('-')).at(-1);\n const selecting = lastArgument !== undefined && SELECTORS.includes(lastArgument.toLowerCase());\n\n return selecting\n ? [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS, ...METHOD_OPTIONS]\n : [...ARGUMENT_OPTIONS, ...FLAG_OPTIONS];\n};\n\nconst complete = (context: CompletionContext): CompletionResult | null => {\n const typed = context.matchBefore(WORD);\n\n // `WORD` also matches the empty string, so without this the popup would open on\n // every space. Asking for completions explicitly still opens it there.\n if (!typed?.text && !context.explicit) return null;\n\n const from = typed?.from ?? context.pos;\n const line = context.state.doc.lineAt(from);\n const options = optionsAfter(\n line.text\n .slice(0, from - line.from)\n .split(/\\s+/)\n .filter(Boolean),\n );\n\n return options.length > 0 ? { from, options, validFor: WORD } : null;\n};\n\nexport const dbt = simpleMode({\n languageData: {\n // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.\n commentTokens: { line: '--', block: { open: '/*', close: '*/' } },\n autocomplete: complete,\n },\n start: [\n { regex: /\"(?:[^\\\\]|\\\\.)*?(?:\"|$)/, token: 'string' },\n // Word-bounded, so `dbtX` is not a dbt step whose first word happens to\n // colour — the same thing the completion source asks of it.\n { regex: /dbt\\b/, token: 'keyword', sol: true },\n { regex: word(COMMAND_PHRASES), token: 'keyword' },\n { regex: word(ARGUMENTS), token: 'variableName' },\n { regex: prefix(METHODS), token: 'propertyName' },\n { regex: prefix(FLAGS), token: 'attributeName' },\n { regex: /(?:@|\\*|,|\\+\\d+|\\d+\\+|\\+)/, token: 'operator' },\n { regex: /'.*'/, token: 'string' },\n { regex: /true|false/, token: 'atom' },\n ],\n});\n","import type { StreamParser } from '@codemirror/language';\n\n/**\n * Port of google/codemirror-mode-jsonnet (Apache-2.0) to CodeMirror 6 tags.\n *\n * - Patterns are anchored with `^`: unanchored, `StringStream.match` scans the whole rest of the line.\n */\n\nconst COMMENT_END = /^\\*\\//;\nconst COMMENT_START = /^\\/\\/|^#/;\nconst C_COMMENT_START = /^\\/\\*/;\nconst TEXT_BLOCK = /^\\|\\|\\|/;\nconst TEXT_BLOCK_END = /^\\s*\\|\\|\\|/;\nconst RAW_DOUBLE = /^\"\"/;\nconst RAW_SINGLE = /^''/;\nconst CLOSE_DOUBLE = /^\"/;\nconst CLOSE_SINGLE = /^'/;\nconst ESCAPE = /^\\\\[\\\\\"'/bfnrt0]/;\nconst UNICODE_ESCAPE = /^\\\\u[0-9a-fA-F]{4}/;\nconst BACKSLASH = /^\\\\/;\nconst IMPORT = /^import(?:str)?\\s*(@?)([\"'])/;\nconst QUOTE = /^(@?)([\"'])/;\nconst ROOT = /^\\$/;\nconst NUMBER = /^(?:\\.\\d+|\\d+\\.?\\d*)(?:e[-+]?\\d+)?/i;\nconst OPERATOR = /^[-+/*=<>!&~^|$%]+/;\nconst IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*/;\n\nconst KEYWORDS: Record<string, 'keyword' | 'atom'> = {\n local: 'keyword',\n self: 'keyword',\n super: 'keyword',\n assert: 'keyword',\n function: 'keyword',\n if: 'keyword',\n then: 'keyword',\n else: 'keyword',\n for: 'keyword',\n in: 'keyword',\n tailstrict: 'keyword',\n error: 'keyword',\n true: 'atom',\n false: 'atom',\n null: 'atom',\n};\n\ntype State = {\n cComment: boolean;\n textBlock: boolean;\n textBlockIndent: number | null;\n string: boolean;\n importString: boolean;\n stringSingle: boolean;\n stringRaw: boolean;\n};\n\nexport const jsonnet: StreamParser<State> = {\n name: 'jsonnet',\n\n // `toggleComment` is a no-op without these, so Mod-/ silently does nothing.\n languageData: { commentTokens: { line: '//', block: { open: '/*', close: '*/' } } },\n\n startState: () => ({\n cComment: false,\n textBlock: false,\n textBlockIndent: null,\n string: false,\n importString: false,\n stringSingle: false,\n stringRaw: false,\n }),\n\n token: (stream, state) => {\n if (state.cComment) {\n if (stream.match(COMMENT_END)) {\n state.cComment = false;\n return 'comment';\n }\n stream.next();\n return 'comment';\n }\n\n // Match the closing `|||` before measuring indent, or a block closed at column 0 never ends.\n if (state.textBlock) {\n if (state.textBlockIndent == null) {\n if (stream.match(TEXT_BLOCK_END)) {\n state.textBlock = false;\n return 'string';\n }\n state.textBlockIndent = stream.indentation();\n }\n if (stream.indentation() >= state.textBlockIndent) {\n stream.skipToEnd();\n return 'string';\n }\n if (stream.match(TEXT_BLOCK_END)) {\n state.textBlock = false;\n return 'string';\n }\n stream.next();\n return 'invalid';\n }\n\n if (state.string || state.importString) {\n const style = state.string ? 'string' : 'meta';\n\n if (state.stringRaw) {\n if (stream.match(state.stringSingle ? RAW_SINGLE : RAW_DOUBLE)) return 'escape';\n } else {\n if (stream.match(ESCAPE)) return 'escape';\n if (stream.match(UNICODE_ESCAPE)) return 'escape';\n if (stream.match(BACKSLASH)) return 'invalid';\n }\n\n if (stream.match(state.stringSingle ? CLOSE_SINGLE : CLOSE_DOUBLE)) {\n state.string = false;\n state.importString = false;\n return style;\n }\n\n stream.next();\n return style;\n }\n\n if (stream.match(COMMENT_START)) {\n stream.skipToEnd();\n return 'comment';\n }\n if (stream.match(C_COMMENT_START)) {\n state.cComment = true;\n return 'comment';\n }\n\n const imported = stream.match(IMPORT);\n if (Array.isArray(imported)) {\n state.importString = true;\n state.stringRaw = imported[1] === '@';\n state.stringSingle = imported[2] === \"'\";\n return 'meta';\n }\n\n const quoted = stream.match(QUOTE);\n if (Array.isArray(quoted)) {\n state.string = true;\n state.stringRaw = quoted[1] === '@';\n state.stringSingle = quoted[2] === \"'\";\n return 'string';\n }\n\n if (stream.match(TEXT_BLOCK)) {\n state.textBlock = true;\n state.textBlockIndent = null;\n return 'string';\n }\n\n if (stream.match(ROOT)) return 'keyword';\n if (stream.match(NUMBER)) return 'number';\n if (stream.match(OPERATOR)) return 'operator';\n\n // Consumed whole so that a keyword's prefix (`locally`) is not styled.\n const identifier = stream.match(IDENTIFIER);\n if (Array.isArray(identifier)) return KEYWORDS[identifier[0]] ?? null;\n\n stream.next();\n return null;\n },\n};\n","import type { ResolvedColorScheme } from '../ThemeProvider/types';\n\n/**\n * Alpha suffixes for the dark-scheme diff and state tints.\n *\n * - Line fill stays subtle for text to read; the gutter sits a step stronger.\n * - `DARK_LINE_ALPHA` is also appended by the static washes in `highlighting.ts` and `search.ts`.\n */\nexport const DARK_LINE_ALPHA = '29'; /* 16% */\nconst DARK_GUTTER_ALPHA = '47'; /* 28% */\n\n/**\n * The two diff fills per scheme: light uses the opaque pastel, dark the `500` hue at low alpha.\n *\n * - Imports nothing, so `MergeEditor` shares it without pulling in CodeMirror via `helpers.ts`.\n * - Shared by `helpers.ts` and `MergeEditor/decorations.ts`, so their alphas cannot drift.\n */\nexport const buildDiffWash = (scheme: ResolvedColorScheme) => {\n const dark = scheme === 'dark';\n\n return {\n line: (hue: string, pastel: string) => (dark ? `${hue}${DARK_LINE_ALPHA}` : pastel),\n gutter: (hue: string, pastel: string) => (dark ? `${hue}${DARK_GUTTER_ALPHA}` : pastel),\n };\n};\n","import { tags } from '@lezer/highlight';\n\nimport colors from '@keboola/tailwind-config/colors';\n\nimport type { ResolvedColorScheme } from '../ThemeProvider/types';\n\n/**\n * The tag colours layered over the stock github palette, per colour scheme.\n *\n * - Imports only tags and ramps, so `scripts/contrast-audit.ts` can measure it.\n * - These override stock rules for the same tag.\n * - Colours are chosen against `background` and `muted` (`variant=\"field\"`); ratios quote both.\n */\nexport const buildSyntaxPalette = (scheme: ResolvedColorScheme, foreground: string) => {\n const dark = scheme === 'dark';\n\n return [\n // Identifiers and brackets carry no colour, as on github.com.\n { tag: [tags.name, tags.special(tags.string), tags.bracket], color: foreground },\n // Functions — light `600` 6.13 / 5.84, dark `300` 9.62 / 7.80.\n { tag: tags.standard(tags.name), color: dark ? colors.purple[300] : colors.purple[600] },\n // Special vars — light `800` 7.26 / 6.92, dark `300` 13.49 / 10.94.\n { tag: tags.special(tags.name), color: dark ? colors.cyan[300] : colors.cyan[800] },\n // Strings — light `800` 7.23 / 6.89, dark `300` 13.53 / 10.97.\n { tag: tags.string, color: dark ? colors.warning[300] : colors.warning[800] },\n // Light-only fixes for stock colours below AA; `CONTRAST-AUDIT.md` has all surfaces.\n ...(dark\n ? []\n : [\n // Keywords — 5.96 / 5.69.\n { tag: [tags.keyword, tags.typeName, tags.typeOperator], color: colors.error[550] },\n // Comments — 6.44 / 6.15.\n { tag: tags.comment, color: colors.neutral[500] },\n // Markdown quotes — 7.15 / 6.82.\n { tag: tags.quote, color: colors.green[900] },\n // Lex errors — 7.81 / 7.45; stock red fails the read-only wash.\n { tag: tags.invalid, color: colors.error[700] },\n ]),\n // Dark only: `githubDarkStyle` has no `escape` rule, so escapes would blend into strings.\n ...(dark ? [{ tag: [tags.escape, tags.url, tags.link], color: colors.blue[300] }] : []),\n ];\n};\n","import { javascript } from '@codemirror/lang-javascript';\nimport { json, jsonParseLinter } from '@codemirror/lang-json';\nimport { python } from '@codemirror/lang-python';\nimport { MSSQL, MySQL, PLSQL, PostgreSQL, StandardSQL } from '@codemirror/lang-sql';\nimport { StreamLanguage } from '@codemirror/language';\nimport { r } from '@codemirror/legacy-modes/mode/r';\nimport { shell } from '@codemirror/legacy-modes/mode/shell';\nimport { toml } from '@codemirror/legacy-modes/mode/toml';\nimport type { LintSource } from '@codemirror/lint';\nimport { linter } from '@codemirror/lint';\nimport { githubDarkInit, githubLightInit } from '@uiw/codemirror-theme-github';\nimport type { BasicSetupOptions } from '@uiw/react-codemirror';\n\nimport { getSqlLanguageSupport } from '@keboola/codemirror-lang-sql';\nimport colors from '@keboola/tailwind-config/colors';\n\nimport { resolveToken } from '../../utils/themeTokens';\nimport type { ResolvedColorScheme } from '../ThemeProvider/types';\n\nimport { dbt } from './modes/dbt';\nimport { jsonnet } from './modes/jsonnet';\nimport { buildDiffWash } from './diffWash';\nimport { buildSyntaxPalette } from './syntaxPalette';\n\n// One list for both the runtime whitelist and the type — a separate `LANGUAGE_MODE[]` copy drifts.\nexport const LANGUAGE_MODES = [\n 'application/json',\n 'text/plain',\n 'text/x-python',\n 'text/x-sql',\n 'text/x-mysql',\n 'text/x-pgsql',\n 'text/x-mssql',\n // Snowflake; the strings are a published prop contract.\n 'text/x-sfsql',\n 'text/x-bqsql',\n 'text/x-plsql',\n 'text/x-rsrc',\n 'text/x-sh',\n 'text/x-toml',\n 'text/jsonnet',\n 'text/x-dbt',\n 'text/javascript',\n 'text/typescript',\n] as const;\n\nexport type LANGUAGE_MODE = (typeof LANGUAGE_MODES)[number];\n\nexport const isLanguageMode = (mode: string): mode is LANGUAGE_MODE =>\n (LANGUAGE_MODES as readonly string[]).includes(mode);\n\n// - `readOnly` is only addressable through `contenteditable`.\n// - `fieldChrome` overrides the read-only wash by re-declaring this key; strings must match exactly.\nexport const READ_ONLY_EDITOR = '&.cm-editor:has(.cm-content[contenteditable=\"false\"])';\nexport const EDITABLE_EDITOR = '&.cm-editor:has(.cm-content[contenteditable=\"true\"])';\n\n/**\n * Editor chrome and the unified merge (diff) wash.\n *\n * - Chrome resolves from live `--*` tokens; fallbacks mirror light-mode values for SSR.\n * - Diff colours are fixed across brands; light/dark pairs from `buildDiffWash`, shared with\n * `MergeEditor/decorations.ts`.\n * - Only `CodeEditor`'s unified merge view uses this; `MergePane` has its own theme.\n */\nexport const buildBaseThemeStyles = (scheme: ResolvedColorScheme) => {\n const { line, gutter } = buildDiffWash(scheme);\n const dark = scheme === 'dark';\n\n return {\n '*': { lineHeight: '20px' },\n '*::selection': {\n backgroundColor: resolveToken('primary', '31 143 255'),\n color: `${resolveToken('primary-foreground', '255 255 255')} !important`,\n },\n // Dark uses `muted`: `secondary` is lighter there and drops `comment` to 4.27:1.\n // `--code-editor-surface` on an ancestor overrides body and gutters.\n [READ_ONLY_EDITOR]: {\n backgroundColor: `var(--code-editor-surface, ${\n dark ? resolveToken('muted', '38 38 45') : resolveToken('secondary', '226 232 240')\n })`,\n },\n [`${READ_ONLY_EDITOR} .cm-gutters`]: {\n backgroundColor: `var(--code-editor-surface, ${resolveToken('border', '229 231 235')})`,\n },\n '&.cm-editor .cm-scroller': { overflowAnchor: 'none' },\n '&.cm-editor, &.cm-editor .cm-scroller': {\n minHeight: '100%',\n flexGrow: 1,\n alignItems: 'stretch !important',\n outline: 'none',\n },\n '.cm-gutter.cm-foldGutter': { display: 'none !important' },\n '.cm-gutter.cm-lineNumbers': { paddingLeft: '20px', paddingRight: '6px' },\n '.cm-gutters': { height: 'auto' },\n\n // merge (diff) view\n '&[class*=\"cm-merge-\"] .cm-deletedLine': {\n backgroundColor: line(colors.error[500], colors.error[100]),\n },\n '&[class*=\"cm-merge-\"] .cm-changedLine': {\n backgroundColor: line(colors.green[500], colors.green[100]),\n },\n '&[class*=\"cm-merge-\"] .cm-deletedLineGutter': {\n backgroundColor: gutter(colors.error[500], colors.error[200]),\n },\n '&[class*=\"cm-merge-\"] .cm-changedLineGutter': {\n backgroundColor: gutter(colors.green[500], colors.green[200]),\n },\n '&[class*=\"cm-merge-\"] .cm-deletedText': {\n background: gutter(colors.error[500], colors.error[200]),\n },\n '&[class*=\"cm-merge-\"] .cm-changedText': {\n background: gutter(colors.green[500], colors.green[200]),\n },\n // Follows the page, not the diff — fixed white would be a light slab under dark.\n '&[class*=\"cm-merge-\"]': {\n backgroundColor: `${resolveToken('background', '249 250 251')} !important`,\n },\n '&[class*=\"cm-merge-\"] .cm-gutters': {\n backgroundColor: `${resolveToken('muted', '241 245 249')} !important`,\n },\n '.cm-changeGutter': { position: 'absolute', zIndex: -1, width: '100%', paddingLeft: 0 },\n '&[class*=\"cm-merge-\"] .cm-changedLine,&[class*=\"cm-merge-\"] .cm-line, &[class*=\"cm-merge-\"] .cm-deletedChunk':\n { paddingLeft: 0 },\n };\n};\n\n// - Fold gutter and active line are hidden by the themes anyway.\n// - `autocompletion`: `CodeEditor` and `SqlEditor` install their own; a second instance competes.\nconst ALWAYS_OFF = {\n autocompletion: false,\n drawSelection: false,\n foldGutter: false,\n foldKeymap: false,\n highlightActiveLine: false,\n highlightActiveLineGutter: false,\n} as const;\n\n// - `basicSetup` enables everything not skipped; a viewer drops editing commands.\n// - Search stays — Mod-f is useful on a viewer.\n// - `history` stays: flipping `readOnly` reconfigures the view, which would drop the undo stack.\nexport const buildBasicSetup = (readOnly: boolean): BasicSetupOptions => ({\n ...ALWAYS_OFF,\n ...(readOnly\n ? {\n closeBrackets: false,\n closeBracketsKeymap: false,\n lintKeymap: false,\n indentOnInput: false,\n rectangularSelection: false,\n dropCursor: false,\n highlightSelectionMatches: false,\n }\n : null),\n});\n\n/**\n * The syntax theme, per colour scheme.\n *\n * - Light github palette fails AA on dark surfaces, so the palette is picked by scheme.\n * - `githubDarkInit` sets the `EditorView.darkTheme` facet that every `&dark` rule keys off.\n * - `caret` and `selectionMatch` are pinned: the initialisers disagree on them.\n */\nexport const buildCustomTheme = (scheme: ResolvedColorScheme) => {\n const foreground = resolveToken('foreground', '30 41 59');\n const init = scheme === 'dark' ? githubDarkInit : githubLightInit;\n\n return init({\n settings: {\n fontFamily: `'SFMono-Regular', 'Menlo', 'Monaco', 'Consolas', 'Liberation Mono', 'Courier New'`,\n background: resolveToken('background', '249 250 251'),\n foreground,\n caret: foreground,\n gutterBackground: resolveToken('muted', '241 245 249'),\n gutterForeground: resolveToken('muted-foreground', '100 116 139'),\n gutterBorder: 'transparent',\n lineHighlight: 'transparent',\n selection: resolveToken('primary', '31 143 255'),\n selectionMatch: resolveToken('primary', '31 143 255', 0.1),\n },\n styles: buildSyntaxPalette(scheme, foreground),\n });\n};\n\nexport const getLanguageMode = (mode?: LANGUAGE_MODE) => {\n switch (mode) {\n case undefined:\n case 'application/json':\n return json();\n case 'text/x-python':\n return python();\n case 'text/x-sql':\n return getSqlLanguageSupport(StandardSQL);\n case 'text/x-mysql':\n return getSqlLanguageSupport(MySQL);\n case 'text/x-pgsql':\n return getSqlLanguageSupport(PostgreSQL);\n case 'text/x-mssql':\n return getSqlLanguageSupport(MSSQL);\n case 'text/x-sfsql':\n return getSqlLanguageSupport('snowflake');\n case 'text/x-bqsql':\n return getSqlLanguageSupport('bigquery');\n case 'text/x-plsql':\n return getSqlLanguageSupport(PLSQL);\n case 'text/x-rsrc':\n return StreamLanguage.define(r);\n case 'text/x-sh':\n return StreamLanguage.define(shell);\n case 'text/x-toml':\n return StreamLanguage.define(toml);\n case 'text/jsonnet':\n return StreamLanguage.define(jsonnet);\n case 'text/x-dbt':\n return StreamLanguage.define(dbt);\n case 'text/javascript':\n return javascript({ jsx: true });\n case 'text/typescript':\n return javascript({ jsx: true, typescript: true });\n // `text/plain` and any unmapped mode: unstyled, not coloured as JSON.\n default:\n return [];\n }\n};\n\n// A read-only editor can't act on lint errors; its underlines are noise.\nexport const shouldLintJson = (mode: LANGUAGE_MODE | undefined, readOnly: boolean): boolean =>\n mode === 'application/json' && !readOnly;\n\n/**\n * Wraps a lint source so a blank document produces no diagnostics.\n *\n * - For optional fields, where empty is valid but `jsonParseLinter` reports an error.\n */\nexport const skipBlankDocument =\n (source: LintSource): LintSource =>\n (view) =>\n view.state.doc.toString().trim() === '' ? [] : source(view);\n\n/**\n * The JSON linter, optionally blind to a blank document.\n *\n * - Opt-in: some callers rely on the marker alone to explain why empty disables their button.\n * - Not derivable from `variant` — whether blank is valid is the field's contract.\n */\nexport const buildJsonLinter = (allowBlankDocument: boolean) => {\n const source = jsonParseLinter();\n\n return linter(allowBlankDocument ? skipBlankDocument(source) : source);\n};\n","import { resolveToken } from '../../utils/themeTokens';\n\nimport { EDITABLE_EDITOR, READ_ONLY_EDITOR } from './helpers';\n\n/** Per-preset parts of an editor's outer chrome, mapped to selectors by `buildChromeStyles`. */\nexport type EditorChrome = {\n surface: string;\n borderColor: string;\n readOnlySurface: string;\n readOnlyBorderColor: string;\n /** `null`: no hover affordance (form inputs). */\n hoverBorderColor: string | null;\n focusBorderColor: string;\n focusRing: string;\n radius: string;\n paddingY: string;\n /** `null` leaves CodeMirror's own 6px/2px line inset alone. */\n paddingX: { left: string; right: string } | null;\n};\n\n/**\n * Mirrors `InputGroup` at each design language's `TextInput` sizing, so it reads as a form field.\n *\n * - Same colour-scheme tokens as `InputGroup`, so it follows light/dark.\n * - argo: `muted`/`input`, the editable argo field's pair.\n * - legacy: `secondary` as `variant=\"secondary\"`; readonly `muted`/`input` as base `InputGroup`.\n */\nexport const buildInputChrome = (isArgo: boolean): EditorChrome => {\n return {\n surface: isArgo\n ? resolveToken('muted', '241 245 249')\n : resolveToken('secondary', '226 232 240'),\n borderColor: isArgo\n ? resolveToken('input', '203 213 225')\n : resolveToken('secondary', '226 232 240'),\n readOnlySurface: resolveToken('muted', '241 245 249'),\n readOnlyBorderColor: resolveToken('input', '203 213 225'),\n hoverBorderColor: null,\n focusBorderColor: isArgo\n ? resolveToken('primary', '37 99 235')\n : resolveToken('ring', '31 143 255'),\n focusRing: `0 0 0 4px ${resolveToken('ring', '31 143 255', isArgo ? 0.5 : 0.3)}`,\n radius: isArgo ? 'var(--radius-lg, 0.25rem)' : '0.25rem',\n // 2px border + 2×this + `.cm-content`'s 4px + 20px line = a one-line `TextInput`:\n // argo `medium` (36px), legacy `default` (40px).\n paddingY: isArgo ? '3px' : '5px',\n // Tops `.cm-line`'s 6px/2px up to an input's 16px text inset.\n paddingX: { left: '10px', right: '14px' },\n };\n};\n\n/** The SQL workspace's notebook cell: a white canvas, not a form control. */\nexport const buildCanvasChrome = (): EditorChrome => ({\n surface: resolveToken('card', '255 255 255'),\n borderColor: 'transparent',\n readOnlySurface: resolveToken('muted', '241 245 249'),\n readOnlyBorderColor: 'transparent',\n hoverBorderColor: resolveToken('ring', '31 143 255'),\n focusBorderColor: resolveToken('ring', '31 143 255'),\n focusRing: `0 0 0 4px ${resolveToken('ring', '31 143 255', 0.3)}`,\n radius: '8px',\n paddingY: '8px',\n paddingX: null,\n});\n\n/** Spread over `buildBaseThemeStyles()`; read-only keys match the base's to replace its wash. */\nexport const buildChromeStyles = (chrome: EditorChrome) => ({\n '&.cm-editor': {\n border: `solid 1px ${chrome.borderColor}`,\n borderRadius: chrome.radius,\n backgroundColor: chrome.surface,\n paddingTop: chrome.paddingY,\n paddingBottom: chrome.paddingY,\n },\n '&.cm-editor :is(.cm-gutters,.cm-scroller)': { backgroundColor: chrome.surface },\n\n ...(chrome.paddingX\n ? {\n // Gutterless only: text aligns with a neighbouring `TextInput`'s; a gutter owns the edge.\n '&.cm-editor:not(:has(.cm-gutters)) .cm-content': {\n paddingLeft: chrome.paddingX.left,\n paddingRight: chrome.paddingX.right,\n },\n }\n : null),\n\n ...(chrome.hoverBorderColor\n ? { [`${EDITABLE_EDITOR}:hover`]: { borderColor: chrome.hoverBorderColor } }\n : null),\n [`${EDITABLE_EDITOR}:focus-within`]: {\n borderColor: chrome.focusBorderColor,\n boxShadow: chrome.focusRing,\n },\n\n [READ_ONLY_EDITOR]: {\n backgroundColor: chrome.readOnlySurface,\n borderColor: chrome.readOnlyBorderColor,\n },\n [`${READ_ONLY_EDITOR} .cm-gutters`]: { backgroundColor: chrome.readOnlySurface },\n [`${READ_ONLY_EDITOR} .cm-scroller`]: { backgroundColor: chrome.readOnlySurface },\n});\n","import { StateEffect, StateField, type Text } from '@codemirror/state';\nimport {\n Decoration,\n type DecorationSet,\n EditorView,\n ViewPlugin,\n type ViewUpdate,\n} from '@codemirror/view';\n\nimport colors from '@keboola/tailwind-config/colors';\n\nimport { findLiteralMatches } from '../../utils/findLiteralMatches';\n\nimport { DARK_LINE_ALPHA } from './diffWash';\n\ntype SearchMatch = {\n from: number;\n to: number;\n localIndex: number;\n};\n\nconst setSearchEffect = StateEffect.define<{\n query: string;\n selectedMatchIndex?: number;\n}>();\n\ntype SearchState = {\n query: string;\n selectedMatchIndex?: number;\n matches: SearchMatch[];\n decorations: DecorationSet;\n};\n\nfunction findMatches(doc: Text, query: string): SearchMatch[] {\n // Before `doc.toString()`, which joins the whole rope.\n if (!query || query.length > doc.length) return [];\n\n return findLiteralMatches(doc.toString(), query).map((from, index) => ({\n from,\n to: from + query.length,\n localIndex: index,\n }));\n}\n\nfunction createDecorations(matches: SearchMatch[], selectedLocalIndex?: number): DecorationSet {\n const decorations = matches.map((match) => {\n const isSelected = match.localIndex === selectedLocalIndex;\n\n const decoration = Decoration.mark({\n class: isSelected ? 'cm-searchMatch-selected' : 'cm-searchMatch',\n });\n\n return decoration.range(match.from, match.to);\n });\n\n return Decoration.set(decorations, true);\n}\n\nconst searchField = StateField.define<SearchState>({\n create() {\n return {\n query: '',\n selectedMatchIndex: undefined,\n matches: [],\n decorations: Decoration.none,\n };\n },\n\n update(state, tr) {\n let newState = state;\n\n for (const effect of tr.effects) {\n if (!effect.is(setSearchEffect)) {\n continue;\n }\n\n const { query, selectedMatchIndex } = effect.value;\n\n const matches = findMatches(tr.state.doc, query);\n\n const decorations = createDecorations(matches, selectedMatchIndex);\n\n newState = {\n query,\n selectedMatchIndex,\n matches,\n decorations,\n };\n }\n\n if (tr.docChanged && newState.query) {\n const matches = findMatches(tr.state.doc, newState.query);\n const decorations = createDecorations(matches, newState.selectedMatchIndex);\n\n newState = {\n ...newState,\n matches,\n decorations,\n };\n }\n\n return newState;\n },\n\n provide: (field) => EditorView.decorations.from(field, (state) => state.decorations),\n});\n\nconst searchViewPlugin = ViewPlugin.fromClass(\n class {\n private lastSelectedIndex?: number;\n\n update(update: ViewUpdate) {\n const state = update.state.field(searchField);\n\n if (\n state.selectedMatchIndex !== undefined &&\n state.selectedMatchIndex !== this.lastSelectedIndex\n ) {\n const match = state.matches[state.selectedMatchIndex];\n\n if (match) {\n requestAnimationFrame(() => {\n update.view.dispatch({\n effects: EditorView.scrollIntoView(match.from, { y: 'center' }),\n });\n });\n }\n\n this.lastSelectedIndex = state.selectedMatchIndex;\n }\n\n if (state.selectedMatchIndex === undefined) {\n this.lastSelectedIndex = undefined;\n }\n }\n },\n);\n\n/**\n * Match and current-match fills, per colour scheme.\n *\n * - `&dark` keeps this a static base theme; it applies when the `EditorView.darkTheme` facet is set.\n * - Dark current match uses `neutral[900]` text: white on `blue[500]` is 2.55:1.\n */\nconst searchTheme = EditorView.baseTheme({\n '.cm-searchMatch': {\n backgroundColor: colors.blue[100],\n },\n '.cm-searchMatch > span': {\n color: `${colors.blue[700]} !important`,\n },\n '.cm-searchMatch-selected': {\n backgroundColor: colors.blue[700],\n },\n '.cm-searchMatch-selected > span': {\n color: `${colors.white} !important`,\n },\n\n '&dark .cm-searchMatch': {\n backgroundColor: `${colors.blue[500]}${DARK_LINE_ALPHA}`,\n },\n '&dark .cm-searchMatch > span': {\n color: `${colors.blue[200]} !important`,\n },\n '&dark .cm-searchMatch-selected': {\n backgroundColor: colors.blue[500],\n },\n '&dark .cm-searchMatch-selected > span': {\n color: `${colors.neutral[900]} !important`,\n },\n});\n\nexport function searchExtension() {\n return [searchField, searchViewPlugin, searchTheme];\n}\n\nexport function updateSearch(view: EditorView, query: string, selectedMatchIndex?: number) {\n view.dispatch({ effects: setSearchEffect.of({ query, selectedMatchIndex }) });\n}\n","import { isMac } from '../../utils';\nimport { Kbd } from '../Kbd';\n\nexport const ToggleComponentHelp = () => (\n <div>\n Use <Kbd>{isMac ? 'Command+/' : 'Ctrl+/'}</Kbd> to toggle comments.\n </div>\n);\n","import { type Extension } from '@codemirror/state';\n\nimport type { ResolvedColorScheme } from '../ThemeProvider/types';\nimport { useThemeAttributes } from '../ThemeProvider/useThemeAttributes';\n\n// Shared across instances: each theme's StyleModule appends rules to a document-level\n// stylesheet, so one module per theme keeps it constant-size however many editors mount.\nconst themeCache = new Map<string, Extension>();\n\n/**\n * A CodeMirror extension shared per `cacheKey`, rebuilt when the brand or light/dark mode changes.\n *\n * - `build` reads live `--*` values off `<html>`, a dependency no deps array can see.\n * - `scheme` comes from the same read as the key, for values that are a light/dark pair.\n * - `cacheKey` must include everything `build` closes over, or different inputs share a theme.\n */\nexport const useThemedExtension = (\n cacheKey: string,\n build: (scheme: ResolvedColorScheme) => Extension,\n): Extension => {\n const { scheme, cacheKey: themeKey } = useThemeAttributes();\n const key = `${themeKey} ${cacheKey}`;\n\n // Filling the module cache during render is idempotent.\n let cached = themeCache.get(key);\n if (!cached) {\n cached = build(scheme);\n themeCache.set(key, cached);\n }\n\n return cached;\n};\n","import { useMemo } from 'react';\nimport { Compartment, type Extension } from '@codemirror/state';\nimport { tooltips, ViewPlugin } from '@codemirror/view';\n\n// Whether this element becomes the containing block of a `position: fixed` descendant.\n// - Encodes the full CSS rule; `contain` and `will-change` are value lists, matched loosely.\n// - `content-visibility` is left to `crops`, the stronger of the two for our purposes.\nconst establishesFixedContainingBlock = (style: CSSStyleDeclaration) =>\n style.transform !== 'none' ||\n style.translate !== 'none' ||\n style.rotate !== 'none' ||\n style.scale !== 'none' ||\n style.perspective !== 'none' ||\n style.filter !== 'none' ||\n style.backdropFilter !== 'none' ||\n /\\b(paint|layout|strict|content)\\b/.test(style.contain) ||\n /\\b(transform|perspective|filter|contain)\\b/.test(style.willChange);\n\n// Crops even a fixed-position descendant; `content-visibility: auto` implies paint\n// containment without showing it in computed `contain`.\nconst crops = (style: CSSStyleDeclaration) =>\n style.overflowX !== 'visible' ||\n style.overflowY !== 'visible' ||\n style.maskImage !== 'none' ||\n style.contentVisibility !== 'visible' ||\n /\\b(paint|strict|content)\\b/.test(style.contain);\n\n/**\n * Where a tooltip can hang uncropped, or `null` for CodeMirror's default.\n *\n * - Hosts above the outermost cropper.\n * - Stops at the fixed containing block; nothing higher can crop.\n * - `<body>` and `<html>` never count as croppers.\n */\nconst findTooltipHost = (from: HTMLElement) => {\n let outermostCropper: HTMLElement | null = null;\n\n for (let node = from.parentElement; node && node !== document.body; node = node.parentElement) {\n const style = getComputedStyle(node);\n\n if (crops(style)) {\n outermostCropper = node;\n } else if (establishesFixedContainingBlock(style)) {\n return outermostCropper?.parentElement ?? node;\n }\n }\n\n return outermostCropper?.parentElement ?? null;\n};\n\n/**\n * `tooltips()`, re-hosted so the completion popup is never cropped.\n *\n * - Must survive a masked, scrolling `Modal` and kbc-ui's `content-visibility: auto` blocks.\n * - Not `document.body`: the popup would sit behind the modal, which disables pointer events there.\n * - The only tooltip host in either editor: CodeMirror takes the first parent configured.\n */\nconst tooltipsExtension = (): Extension => {\n // A compartment, because a prop-driven full reconfigure drops appended config but keeps compartments.\n const layer = new Compartment();\n\n return [\n layer.of(tooltips()),\n ViewPlugin.define((view) => {\n // Deferred: a plugin cannot dispatch while its view is being built, and reading styles\n // here would force a layout flush mid-commit. One-shot; later ancestor changes are missed.\n const scheduled = setTimeout(() => {\n if (!view.dom.isConnected) return;\n\n const parent = findTooltipHost(view.dom);\n if (parent) view.dispatch({ effects: layer.reconfigure(tooltips({ parent })) });\n });\n\n return { destroy: () => clearTimeout(scheduled) };\n }),\n ];\n};\n\n/**\n * The tooltips extension, built once per editor; a rebuild would drop the resolved host.\n */\nexport const useTooltipsExtension = () => useMemo(tooltipsExtension, []);\n","import type { Completion, CompletionContext, CompletionSource } from '@codemirror/autocomplete';\n\nimport { useStableCallback } from '../../hooks/useStableCallback';\n\nexport type EditorVariable = { name: string; value?: string };\n\n// Ranks variables above the language's many same-prefix keywords.\nconst BOOST = 2000;\n\n// - One brace or two: `closeBrackets` turns a typed `{` into `{}`.\n// - One name charset throughout; a narrower second one would start the range mid-name and never match.\nconst NAME = String.raw`[\\w-]*`;\nconst AT_CARET = new RegExp(String.raw`(?:\\{{1,2} ?)?${NAME}$`);\nconst NAME_AT_END = new RegExp(`${NAME}$`);\nconst OPENING = /\\{{1,2} ?$/;\nconst CLOSING = /^ ?\\}{1,2}/;\n\n/**\n * Completes a mustache-style `{{name}}` placeholder.\n */\nexport const completeVariables = (variables: EditorVariable[] = []): CompletionSource => {\n if (variables.length === 0) return () => null;\n\n const options: Completion[] = variables.map(({ name, value }) => ({\n // Bare name: the only spelling both editors' filters match, braces typed or not.\n label: name,\n displayLabel: `{{${name}}}`,\n detail: value,\n type: 'variable',\n boost: BOOST,\n apply: (view, completion, from, to) => {\n const { doc } = view.state;\n const line = doc.lineAt(from);\n const insert = `{{${completion.label}}}`;\n\n // Braces are found, not assumed: `closeBrackets` may have added a closing one.\n const opening = OPENING.exec(doc.sliceString(line.from, from));\n const closing = CLOSING.exec(doc.sliceString(to, line.to));\n const start = opening ? from - opening[0].length : from;\n const end = closing ? to + closing[0].length : to;\n\n view.dispatch({\n changes: { from: start, to: end, insert },\n selection: { anchor: start + insert.length },\n });\n },\n }));\n\n return (context: CompletionContext) => {\n const match = context.matchBefore(AT_CARET);\n\n if (!match?.text) return null;\n\n const [name = ''] = NAME_AT_END.exec(match.text) ?? [];\n\n return { from: match.to - name.length, options };\n };\n};\n\n/**\n * The completion source both editors install, with a stable identity.\n *\n * - It keys their extension memo, while callers pass a fresh array on every store push.\n * - CodeMirror asks per request, so it still sees the latest variables.\n */\nexport const useVariableCompletion = (variables: EditorVariable[] = []): CompletionSource =>\n useStableCallback(completeVariables(variables));\n","import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';\nimport type { KeyboardEvent, ReactNode } from 'react';\nimport type { CompletionSource } from '@codemirror/autocomplete';\nimport { autocompletion, completeAnyWord } from '@codemirror/autocomplete';\nimport { unifiedMergeView } from '@codemirror/merge';\nimport { EditorView, keymap, placeholder as cmPlaceholder } from '@codemirror/view';\nimport CodeMirror, {\n EditorState,\n type Extension,\n type ReactCodeMirrorRef,\n} from '@uiw/react-codemirror';\n\nimport { keyCodes } from '../../constants/keyCodes';\nimport { useStableCallback } from '../../hooks/useStableCallback';\nimport { cn } from '../../utils';\nimport { HelpBlock } from '../HelpBlock';\nimport { useArgoDesign } from '../ThemeProvider/context';\n\nimport { ButtonToolbar } from './ButtonToolbar';\nimport { buildChromeStyles, buildInputChrome } from './editorChrome';\nimport type { LANGUAGE_MODE } from './helpers';\nimport {\n buildBaseThemeStyles,\n buildBasicSetup,\n buildCustomTheme,\n buildJsonLinter,\n getLanguageMode,\n shouldLintJson,\n} from './helpers';\nimport { searchExtension, updateSearch } from './search';\nimport { ToggleComponentHelp } from './ToggleComponentHelp';\nimport { useThemedExtension } from './tokenTheme';\nimport { useTooltipsExtension } from './tooltips';\nimport { type EditorVariable, useVariableCompletion } from './variableCompletion';\n\ntype Props = {\n value: string;\n previousValue?: string;\n /** `'field'`: `InputGroup` chrome, sized to content (don't pin height). `'plain'`: full-bleed panel. */\n variant?: 'plain' | 'field';\n mode?: LANGUAGE_MODE;\n placeholder?: string;\n /** Screen-reader name: the editor has no visible label of its own. */\n ariaLabel?: string;\n /** Prefer over `ariaLabel` inside a form. */\n ariaLabelledBy?: string;\n ariaDescribedBy?: string;\n /** Visual error styling is the caller's (`variant=\"field\"`). */\n ariaInvalid?: boolean;\n ariaRequired?: boolean;\n /** JSON modes: a blank document is not a parse error. Off by default: the mark explains a disabled Save. */\n allowBlankDocument?: boolean;\n /** Bound on CodeMirror's content node (the wrapper is not what gets focused). */\n onBlur?: () => void;\n /** Highlights matches; the find UI is the caller's. Omit both props to skip the search extension. */\n searchQuery?: string;\n searchMatchIndex?: number;\n readOnly?: boolean;\n /** Refuses edits without changing the look, e.g. during a save; `readOnly` makes a greyed viewer. */\n inputLocked?: boolean;\n /** One word per label (a space breaks matching; phrases go in `completionSource`). Pass a stable array. */\n autocompletions?: string[];\n /** Cursor-dependent completions; wins over `autocompletions` / `completeAny`. Memoize it. */\n completionSource?: CompletionSource;\n /** Completed into `{{name}}`, alongside `completionSource`. */\n variables?: EditorVariable[];\n /** `false` silences every source, the language's own included (e.g. shell mode used only for colours). */\n withCompletions?: boolean;\n extraKeys?: Record<string, () => void>;\n withToggleCommentHint?: boolean;\n withAutofocus?: boolean;\n withLineNumbers?: boolean;\n withLineWrapping?: boolean;\n withCollapseUnchanged?: boolean;\n withCopyButton?: boolean;\n completeAny?: boolean;\n help?: ReactNode;\n helpPostfix?: ReactNode;\n /** Toolbar actions beside the copy button; pass `size=\"icon-xs\"` buttons to fit the 28px chip. */\n renderAdditionalButtons?: (value?: string) => ReactNode;\n className?: string;\n} & (\n | { readOnly: true; onChange?: never }\n // `boolean`, not `false`: a permission-locked field still needs its handler when editable.\n | { readOnly?: boolean; onChange: (value: string) => void }\n);\n\nconst emptyObject = {};\n\nexport const CodeEditor = ({\n value,\n previousValue,\n onChange,\n variant = 'plain',\n mode = 'application/json',\n placeholder = '',\n ariaLabel,\n ariaLabelledBy,\n ariaDescribedBy,\n ariaInvalid,\n ariaRequired,\n allowBlankDocument = false,\n onBlur,\n searchQuery,\n searchMatchIndex,\n readOnly = false,\n inputLocked = false,\n autocompletions,\n completionSource,\n variables,\n withCompletions = true,\n extraKeys = emptyObject,\n withToggleCommentHint = false,\n withAutofocus = false,\n withLineNumbers = true,\n withLineWrapping = true,\n withCollapseUnchanged = false,\n withCopyButton = false,\n completeAny = false,\n help = null,\n helpPostfix = null,\n renderAdditionalButtons,\n className,\n}: Props) => {\n // A new handler identity rebuilds CodeMirror's extension tree; callers pass inline arrows.\n const handleChange = useStableCallback((next: string) => onChange?.(next));\n const handleBlur = useStableCallback(() => onBlur?.());\n\n // Presence, not truthiness, keeps the extension set stable while the query changes.\n const withSearch = searchQuery !== undefined;\n const withBlur = onBlur !== undefined;\n const editorRef = useRef<ReactCodeMirrorRef>(null);\n\n // `null` when empty, so the extension is left out.\n const contentAria = useMemo(() => {\n const attributes: Record<string, string> = {};\n if (ariaLabel !== undefined) attributes['aria-label'] = ariaLabel;\n if (ariaLabelledBy !== undefined) attributes['aria-labelledby'] = ariaLabelledBy;\n if (ariaDescribedBy !== undefined) attributes['aria-describedby'] = ariaDescribedBy;\n // Stringified: `contentAttributes` would drop a boolean `false`.\n if (ariaInvalid !== undefined) attributes['aria-invalid'] = String(ariaInvalid);\n if (ariaRequired !== undefined) attributes['aria-required'] = String(ariaRequired);\n return Object.keys(attributes).length > 0 ? attributes : null;\n }, [ariaLabel, ariaLabelledBy, ariaDescribedBy, ariaInvalid, ariaRequired]);\n\n useEffect(() => {\n const view = editorRef.current?.view;\n if (view && withSearch) updateSearch(view, searchQuery, searchMatchIndex);\n }, [withSearch, searchQuery, searchMatchIndex]);\n\n // A view created with a query already set (remount, tab switch) needs it applied on build.\n const handleCreateEditor = useStableCallback((view: EditorView) => {\n if (searchQuery) updateSearch(view, searchQuery, searchMatchIndex);\n });\n\n // Callers pass this inline; only the key set rebuilds the keymap, handlers are read on press.\n const extraKeysRef = useRef(extraKeys);\n useLayoutEffect(() => {\n extraKeysRef.current = extraKeys;\n });\n\n const boundKeysSignature = Object.keys(extraKeys).join('\\n');\n const boundKeys = useMemo(\n () => boundKeysSignature.split('\\n').filter(Boolean),\n [boundKeysSignature],\n );\n\n const tooltipLayer = useTooltipsExtension();\n\n // Built here, not inside `languageData.of`, which runs per completion request.\n const variableCompletion = useVariableCompletion(variables);\n\n // Key has no component prefix: shared with `SqlEditor`.\n const customTheme = useThemedExtension('editor:syntax', buildCustomTheme);\n\n // The brand is in the cache key: `useThemedExtension` caches per key and tracks only `<html>`.\n const isArgo = useArgoDesign();\n const isField = variant === 'field';\n const baseTheme = useThemedExtension(\n isField ? `code-editor:field:${isArgo ? 'argo' : 'legacy'}` : 'code-editor:chrome',\n (scheme) =>\n // `dark` activates every `&dark` rule (ours and CodeMirror's); set here so swapping the\n // github palette in `buildCustomTheme` cannot turn them off.\n EditorView.theme(\n {\n ...buildBaseThemeStyles(scheme),\n ...(isField ? buildChromeStyles(buildInputChrome(isArgo)) : null),\n },\n { dark: scheme === 'dark' },\n ),\n );\n\n const commonExtensions: Extension[] = useMemo(() => {\n const callerCompletions =\n completionSource ??\n (completeAny ? completeAnyWord : autocompletions?.length ? autocompletions : null);\n\n // An empty list is left out, or CodeMirror runs a never-matching source on every keystroke.\n const completionEntries = [\n ...(callerCompletions ? [{ autocomplete: callerCompletions }] : []),\n { autocomplete: variableCompletion },\n ];\n\n return [\n getLanguageMode(mode),\n shouldLintJson(mode, readOnly) ? buildJsonLinter(allowBlankDocument) : [],\n withLineWrapping ? EditorView.lineWrapping : [],\n EditorState.languageData.of(() => completionEntries),\n keymap.of(\n boundKeys.map((key) => ({\n key,\n run: () => {\n extraKeysRef.current[key]?.();\n return true;\n },\n })),\n ),\n readOnly || !withCompletions\n ? []\n : [\n // The only `autocompletion()` (`buildBasicSetup` disables basicSetup's). Not gated on\n // the completion props, so the language's own vocabulary still completes.\n autocompletion(),\n ],\n // On the focused content node (`div[role=\"textbox\"]`), not the wrapper.\n contentAria ? EditorView.contentAttributes.of(contentAria) : [],\n withBlur ? EditorView.domEventHandlers({ blur: handleBlur }) : [],\n withSearch ? searchExtension() : [],\n tooltipLayer,\n baseTheme,\n ];\n }, [\n autocompletions,\n completionSource,\n variableCompletion,\n completeAny,\n withCompletions,\n boundKeys,\n mode,\n readOnly,\n allowBlankDocument,\n withLineWrapping,\n baseTheme,\n contentAria,\n withBlur,\n handleBlur,\n withSearch,\n tooltipLayer,\n ]);\n\n const extensions = useMemo(() => {\n return [\n ...commonExtensions,\n cmPlaceholder(placeholder),\n EditorView.editable.of(!readOnly),\n // The lock is only this facet: `contenteditable` drives the read-only wash and `basicSetup`\n // holds the undo history, so neither is reconfigured.\n EditorState.readOnly.of(readOnly || inputLocked),\n previousValue\n ? unifiedMergeView({\n original: previousValue,\n mergeControls: false,\n highlightChanges: false,\n collapseUnchanged: withCollapseUnchanged ? {} : undefined,\n })\n : [],\n ];\n }, [commonExtensions, placeholder, readOnly, inputLocked, previousValue, withCollapseUnchanged]);\n\n const config = useMemo(() => {\n return {\n ...buildBasicSetup(readOnly),\n lineNumbers: withLineNumbers,\n // Mod-f would open CodeMirror's own search panel beside the caller's.\n ...(withSearch ? { searchKeymap: false } : null),\n };\n }, [withLineNumbers, readOnly, withSearch]);\n\n return (\n // oxlint-disable-next-line jsx-a11y/no-static-element-interactions\n <div\n data-variant={variant}\n className={cn(\n // Scoped to CodeMirror's box so the toolbar needn't undo it with `!important`.\n 'tw:relative tw:flex tw:min-h-0 tw:flex-col tw:[&_.cm-mergeViewEditor]:overflow-visible tw:[&_.cm-mergeViewEditors]:h-full tw:[&_.cm-mergeView]:h-full tw:[&_>.cm-theme]:h-full',\n // Field: transparent so square corners don't show; visible so the focus ring isn't cropped.\n isField\n ? 'tw:[&_>.cm-theme]:overflow-visible tw:[&_>.cm-theme]:bg-transparent'\n : 'tw:[&_>.cm-theme]:overflow-auto tw:[&_>.cm-theme]:bg-background',\n className,\n )}\n onKeyDown={(event: KeyboardEvent) => {\n if (event.key === keyCodes.ESCAPE) {\n event.stopPropagation();\n }\n }}\n >\n <ButtonToolbar value={withCopyButton ? value : undefined}>\n {renderAdditionalButtons?.(value)}\n </ButtonToolbar>\n <CodeMirror\n ref={editorRef}\n onCreateEditor={handleCreateEditor}\n theme={customTheme}\n value={value}\n onChange={handleChange}\n extensions={extensions}\n autoFocus={withAutofocus}\n basicSetup={config}\n />\n {!readOnly && (withToggleCommentHint || help || helpPostfix) && (\n <HelpBlock className=\"tw:mt-2 tw:flex tw:flex-wrap tw:gap-1\">\n {help}\n {withToggleCommentHint ? <ToggleComponentHelp /> : null}\n {helpPostfix}\n </HelpBlock>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import { useStableCallback } from "./internal/hooks/useStableCallback.js";
2
+ import { toast as toast$1 } from "./toast-CyXEdaCZ.js";
3
+ import { useEffect, useId, useRef } from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import { Toaster } from "sonner";
6
+ //#region src/components/Toast/useNotification.tsx
7
+ /**
8
+ * A persistent, system-driven notification (trial expiry, upgrade prompt, billing alert).
9
+ *
10
+ * - Stays until the user dismisses it or the component unmounts; `toast()` is for transient
11
+ * feedback after a user action.
12
+ * - A visible one updates in place when its string `title` or `description` changes; other
13
+ * options apply the next time it shows.
14
+ */
15
+ const useNotification = ({ enabled = true, remindAfter, ...toastOptions }) => {
16
+ const fallbackId = useId();
17
+ const toastId = toastOptions.id ?? fallbackId;
18
+ const isShownRef = useRef(false);
19
+ const reminderRef = useRef(void 0);
20
+ const show = useStableCallback(() => {
21
+ isShownRef.current = true;
22
+ toast$1({
23
+ ...toastOptions,
24
+ id: toastId,
25
+ duration: toastOptions.duration ?? Infinity,
26
+ onDismiss: (dismissed) => {
27
+ toastOptions.onDismiss?.(dismissed);
28
+ if (!isShownRef.current) return;
29
+ isShownRef.current = false;
30
+ if (remindAfter !== void 0) reminderRef.current = setTimeout(show, remindAfter);
31
+ }
32
+ });
33
+ });
34
+ useEffect(() => {
35
+ if (!enabled) return;
36
+ const frameId = requestAnimationFrame(show);
37
+ return () => {
38
+ cancelAnimationFrame(frameId);
39
+ clearTimeout(reminderRef.current);
40
+ if (!isShownRef.current) return;
41
+ isShownRef.current = false;
42
+ toast$1.dismiss(toastId);
43
+ };
44
+ }, [
45
+ enabled,
46
+ show,
47
+ toastId
48
+ ]);
49
+ const titleText = typeof toastOptions.title === "string" ? toastOptions.title : void 0;
50
+ const descriptionText = typeof toastOptions.description === "string" ? toastOptions.description : void 0;
51
+ useEffect(() => {
52
+ if (isShownRef.current) show();
53
+ }, [
54
+ titleText,
55
+ descriptionText,
56
+ show
57
+ ]);
58
+ };
59
+ //#endregion
60
+ //#region src/components/Toast/Toaster.tsx
61
+ const DEFAULT_STYLES = { "--width": "512px" };
62
+ const stopPropagation = (event) => event.stopPropagation();
63
+ const Toaster$1 = ({ gap = 12, visibleToasts = 5, ...props }) => /* @__PURE__ */ jsx("div", {
64
+ onPointerDown: stopPropagation,
65
+ children: /* @__PURE__ */ jsx(Toaster, {
66
+ ...props,
67
+ gap,
68
+ visibleToasts,
69
+ className: "tw:pointer-events-auto tw:flex tw:w-full tw:max-w-lg tw:justify-center",
70
+ style: DEFAULT_STYLES
71
+ })
72
+ });
73
+ //#endregion
74
+ export { Toaster$1 as Toaster, useNotification };
75
+
76
+ //# sourceMappingURL=Toast-NrOdDDru.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast-NrOdDDru.js","names":["Toaster","SonnerToaster"],"sources":["../src/components/Toast/useNotification.tsx","../src/components/Toast/Toaster.tsx"],"sourcesContent":["import { useEffect, useId, useRef } from 'react';\n\nimport { useStableCallback } from '../../hooks/useStableCallback';\n\nimport { toast, type ToastOptions } from './toast';\n\ntype Props = {\n enabled?: boolean;\n /** Shows the notification again this many ms after the user dismisses it, while still enabled. */\n remindAfter?: number;\n} & ToastOptions;\n\n/**\n * A persistent, system-driven notification (trial expiry, upgrade prompt, billing alert).\n *\n * - Stays until the user dismisses it or the component unmounts; `toast()` is for transient\n * feedback after a user action.\n * - A visible one updates in place when its string `title` or `description` changes; other\n * options apply the next time it shows.\n */\nexport const useNotification = ({ enabled = true, remindAfter, ...toastOptions }: Props) => {\n const fallbackId = useId();\n const toastId = toastOptions.id ?? fallbackId;\n const isShownRef = useRef(false);\n const reminderRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n\n const show = useStableCallback(() => {\n isShownRef.current = true;\n toast({\n ...toastOptions,\n id: toastId,\n duration: toastOptions.duration ?? Infinity,\n onDismiss: (dismissed) => {\n toastOptions.onDismiss?.(dismissed);\n // sonner reports the hook's own cleanup dismissal too; that one is already hidden\n if (!isShownRef.current) return;\n\n isShownRef.current = false;\n if (remindAfter !== undefined) reminderRef.current = setTimeout(show, remindAfter);\n },\n });\n });\n\n useEffect(() => {\n if (!enabled) return;\n const frameId = requestAnimationFrame(show);\n\n return () => {\n cancelAnimationFrame(frameId);\n clearTimeout(reminderRef.current);\n if (!isShownRef.current) return;\n\n isShownRef.current = false;\n toast.dismiss(toastId);\n };\n }, [enabled, show, toastId]);\n\n const titleText = typeof toastOptions.title === 'string' ? toastOptions.title : undefined;\n const descriptionText =\n typeof toastOptions.description === 'string' ? toastOptions.description : undefined;\n\n useEffect(() => {\n if (isShownRef.current) show();\n }, [titleText, descriptionText, show]);\n};\n","import type { ComponentProps, PointerEvent } from 'react';\nimport { Toaster as SonnerToaster } from 'sonner';\n\ntype ToasterProps = ComponentProps<typeof SonnerToaster>;\n\nconst DEFAULT_STYLES = {\n '--width': '512px', // match max-w-lg\n} as React.CSSProperties;\n\nconst stopPropagation = (event: PointerEvent) => event.stopPropagation();\n\nexport const Toaster = ({ gap = 12, visibleToasts = 5, ...props }: ToasterProps) => (\n // Wrapper prevents toast clicks from reaching Radix Dialog's DismissableLayer,\n // which would otherwise close the modal on any \"outside\" pointer event.\n // oxlint-disable-next-line jsx-a11y/no-static-element-interactions\n <div onPointerDown={stopPropagation}>\n <SonnerToaster\n {...props}\n gap={gap}\n visibleToasts={visibleToasts}\n className=\"tw:pointer-events-auto tw:flex tw:w-full tw:max-w-lg tw:justify-center\"\n style={DEFAULT_STYLES}\n />\n </div>\n);\n"],"mappings":";;;;;;;;;;;;;;AAoBA,MAAa,mBAAmB,EAAE,UAAU,MAAM,aAAa,GAAG,mBAA0B;CAC1F,MAAM,aAAa,MAAM;CACzB,MAAM,UAAU,aAAa,MAAM;CACnC,MAAM,aAAa,OAAO,KAAK;CAC/B,MAAM,cAAc,OAAsC,KAAA,CAAS;CAEnE,MAAM,OAAO,wBAAwB;EACnC,WAAW,UAAU;EACrB,QAAM;GACJ,GAAG;GACH,IAAI;GACJ,UAAU,aAAa,YAAY;GACnC,YAAY,cAAc;IACxB,aAAa,YAAY,SAAS;IAElC,IAAI,CAAC,WAAW,SAAS;IAEzB,WAAW,UAAU;IACrB,IAAI,gBAAgB,KAAA,GAAW,YAAY,UAAU,WAAW,MAAM,WAAW;GACnF;EACF,CAAC;CACH,CAAC;CAED,gBAAgB;EACd,IAAI,CAAC,SAAS;EACd,MAAM,UAAU,sBAAsB,IAAI;EAE1C,aAAa;GACX,qBAAqB,OAAO;GAC5B,aAAa,YAAY,OAAO;GAChC,IAAI,CAAC,WAAW,SAAS;GAEzB,WAAW,UAAU;GACrB,QAAM,QAAQ,OAAO;EACvB;CACF,GAAG;EAAC;EAAS;EAAM;CAAO,CAAC;CAE3B,MAAM,YAAY,OAAO,aAAa,UAAU,WAAW,aAAa,QAAQ,KAAA;CAChF,MAAM,kBACJ,OAAO,aAAa,gBAAgB,WAAW,aAAa,cAAc,KAAA;CAE5E,gBAAgB;EACd,IAAI,WAAW,SAAS,KAAK;CAC/B,GAAG;EAAC;EAAW;EAAiB;CAAI,CAAC;AACvC;;;AC3DA,MAAM,iBAAiB,EACrB,WAAW,QACb;AAEA,MAAM,mBAAmB,UAAwB,MAAM,gBAAgB;AAEvE,MAAaA,aAAW,EAAE,MAAM,IAAI,gBAAgB,GAAG,GAAG,YAIxD,oBAAC,OAAD;CAAK,eAAe;CAClB,UAAA,oBAACC,SAAD;EACE,GAAI;EACC;EACU;EACf,WAAU;EACV,OAAO;CACR,CAAA;AACE,CAAA"}
package/dist/editors.js CHANGED
@@ -5,7 +5,7 @@ import { useStableCallback } from "./internal/hooks/useStableCallback.js";
5
5
  import { FieldItem, useFieldContext } from "./FieldItem-BHViBJS3.js";
6
6
  import { CHANGE_CLASS } from "./internal/components/MergeEditor/constants.js";
7
7
  import { resolveToken } from "./themeTokens-7DEab0kp.js";
8
- import { CodeEditor, LANGUAGE_MODES, buildBaseThemeStyles, buildBasicSetup, buildCanvasChrome, buildChromeStyles, buildCustomTheme, buildDiffWash, isLanguageMode, searchExtension, updateSearch, useThemedExtension, useTooltipsExtension, useVariableCompletion } from "./CodeEditor-jZMw1ioj.js";
8
+ import { CodeEditor, LANGUAGE_MODES, buildBaseThemeStyles, buildBasicSetup, buildCanvasChrome, buildChromeStyles, buildCustomTheme, buildDiffWash, isLanguageMode, searchExtension, updateSearch, useThemedExtension, useTooltipsExtension, useVariableCompletion } from "./CodeEditor-Df7VVx08.js";
9
9
  import { useCallback, useEffect, useMemo, useRef } from "react";
10
10
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
11
11
  import { Decoration, EditorView, GutterMarker, ViewPlugin, gutter, gutterLineClass } from "@codemirror/view";
package/dist/index.d.ts CHANGED
@@ -5092,9 +5092,13 @@ type Props$7 = {
5092
5092
  currentStep?: number;
5093
5093
  totalSteps?: number;
5094
5094
  renderPreview?: (content: string) => ReactNode;
5095
+ /** Focuses the card on mount, unless the focused field already holds text. */
5096
+ autoFocus?: boolean;
5097
+ /** ⌥1–⌥9 picks an option from anywhere on the page, text fields included. */
5098
+ enableShortcuts?: boolean;
5095
5099
  className?: string;
5096
5100
  };
5097
- declare const Question: ({ question, header, options, multiSelect, selectedOptionIds, onSelectionChange, customAnswer, onCustomAnswerChange, onCustomAnswerConfirm, showCustomAnswer, customAnswerPlaceholder, showSkip, onSkip, onClose, onNext, submitTooltip, onPrevious, currentStep, totalSteps, renderPreview, className }: Props$7) => import("react").JSX.Element;
5101
+ declare const Question: ({ question, header, options, multiSelect, selectedOptionIds, onSelectionChange, customAnswer, onCustomAnswerChange, onCustomAnswerConfirm, showCustomAnswer, customAnswerPlaceholder, showSkip, onSkip, onClose, onNext, submitTooltip, onPrevious, currentStep, totalSteps, renderPreview, autoFocus, enableShortcuts, className }: Props$7) => import("react").JSX.Element;
5098
5102
  //#endregion
5099
5103
  //#region src/blocks/AIKit/QuestionBlock.d.ts
5100
5104
  type QuestionStep = {
@@ -5125,9 +5129,11 @@ type Props$122 = {
5125
5129
  disabled?: boolean;
5126
5130
  onClick: () => void;
5127
5131
  icon?: ReactNode;
5132
+ /** `bubble`: shaped like a chat message and outlined — a reply waiting to be sent. */
5133
+ variant?: 'row' | 'bubble';
5128
5134
  className?: string;
5129
5135
  };
5130
- declare const SuggestedPrompt: ({ label, disabled, onClick, icon, className }: Props$122) => import("react").JSX.Element;
5136
+ declare const SuggestedPrompt: ({ label, disabled, onClick, icon, variant, className }: Props$122) => import("react").JSX.Element;
5131
5137
  //#endregion
5132
5138
  //#region src/blocks/AIKit/ThinkingIndicator.d.ts
5133
5139
  type ThinkingIndicatorProps = {
@@ -5379,18 +5385,18 @@ declare namespace toast {
5379
5385
  //#region src/components/Toast/useNotification.d.ts
5380
5386
  type Props$111 = {
5381
5387
  enabled?: boolean;
5382
- } & Parameters<typeof toast>[0];
5388
+ /** Shows the notification again this many ms after the user dismisses it, while still enabled. */
5389
+ remindAfter?: number;
5390
+ } & ToastOptions;
5383
5391
  /**
5384
- * Declarative notification component built on top of sonner/toast.
5385
- *
5386
- * Use `Notification` for persistent, system-driven messages that require user acknowledgment
5387
- * (e.g., trial expiration warnings, upgrade prompts, billing alerts).
5388
- * The notification stays visible until the user dismisses it or the component unmounts.
5392
+ * A persistent, system-driven notification (trial expiry, upgrade prompt, billing alert).
5389
5393
  *
5390
- * Use `toast()` for transient feedback after a user action
5391
- * (e.g., "Saved", "Copied", "Deleted") that auto-dismisses after a few seconds.
5394
+ * - Stays until the user dismisses it or the component unmounts; `toast()` is for transient
5395
+ * feedback after a user action.
5396
+ * - A visible one updates in place when its string `title` or `description` changes; other
5397
+ * options apply the next time it shows.
5392
5398
  */
5393
- declare const useNotification: ({ enabled, ...toastOptions }: Props$111) => void;
5399
+ declare const useNotification: ({ enabled, remindAfter, ...toastOptions }: Props$111) => void;
5394
5400
  //#endregion
5395
5401
  //#region src/components/Toast/Toaster.d.ts
5396
5402
  type ToasterProps = ComponentProps<typeof Toaster$1>;
@@ -7190,6 +7196,34 @@ declare const setServerFieldErrors: (form: AnyFormApi, errors: readonly ServerFi
7190
7196
  */
7191
7197
  declare const setSubmitError: (form: AnyFormApi, message: string) => void;
7192
7198
  //#endregion
7199
+ //#region src/hooks/useAltDigitHotkey.d.ts
7200
+ /** The highest digit a numbered option can be picked with. */
7201
+ declare const MAX_DIGIT_HOTKEY = 9;
7202
+ /**
7203
+ * The 1–9 digit a key press names, or `null`.
7204
+ *
7205
+ * - Reads `code`, not `key`: on a Mac ⌥ plus a digit types `¡™£`, and some layouts need ⇧ for digits.
7206
+ * - Top-row and numpad digits both count; `0` does not.
7207
+ */
7208
+ declare const digitFromKeyCode: (code: string) => number | null;
7209
+ type Options$1 = {
7210
+ /** How many numbered targets there are; digits past it, and past 9, do nothing. */
7211
+ count: number;
7212
+ /** Receives the 0-based index of the digit pressed. */
7213
+ onDigit: (index: number) => void;
7214
+ enabled?: boolean;
7215
+ /** The list's element; while a modal hides it (`aria-hidden`, `inert`), the keys pass through. */
7216
+ ref?: RefObject<HTMLElement | null>;
7217
+ };
7218
+ /**
7219
+ * ⌥1–⌥9 anywhere on the page, text fields included.
7220
+ *
7221
+ * - Prevents the default, so a field focused at the time gets no `¡™£`.
7222
+ * - Skips an event a handler before it already took, so two lists on screen never both fire.
7223
+ * - Leaves numpad digits alone: on Windows ⌥ plus numpad digits types an Alt code.
7224
+ */
7225
+ declare const useAltDigitHotkey: ({ count, onDigit, enabled, ref }: Options$1) => void;
7226
+ //#endregion
7193
7227
  //#region src/hooks/useAutosizeInput.d.ts
7194
7228
  type UseAutosizeInputOptions = {
7195
7229
  value?: string;
@@ -7329,5 +7363,5 @@ declare const contrastRatio: (fg: string, bg: string) => number;
7329
7363
  /** WCAG level for normal-size text at a given ratio. */
7330
7364
  declare const wcagLevel: (ratio: number) => 'AAA' | 'AA' | 'fail';
7331
7365
  //#endregion
7332
- export { Alert, AlertModal, AnswerActions, AnswerSummary, type AnswerItem as AnswerSummaryItem, type Props as AnswerSummaryProps, type Variant as AnswerSummaryVariant, AnswerVote, AppShell, type AppShellHeaderSpan, type AppShellSlot, ArgoDesignContext, AuthLayout, type RootProps as AuthLayoutProps, AutoSaveTextarea, Avatar, BLANK_VALUES, Badge, type Brand, BrandEditor, type BrandEditorProps, BrandId, BrandLogo, Breadcrumb, Button, ButtonGroup, ButtonInline, Calendar, type CalendarProps, Card, type ChangeClassification, ChartPanel, type RootProps$1 as ChartPanelProps, ChatInlineIcon, Checkbox, ChipEditor, type Props$1 as ChipEditorProps, Clipboard, ClipboardButton, ClipboardInline, Collapsible, CollapsiblePanel, CollapsibleStepHeader, ColorInput, ColorModeSwitch, ColorScheme, type ColorSlot, Combobox, ComboboxField, Command, CommandGroup, CommandInput, CommandItem, CommandList, ConflictStatusIndicator, CopyField, DEFAULT_COLOR_SCHEME, DEFAULT_FALLBACK_FONT, DEFAULT_FONT_OPTIONS, DEFAULT_BRAND_ID as DEFAULT_KEBOOLA_BRAND_ID, DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM, DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX, DIAGRAM_LANGUAGES, DashboardHero, type RootProps$2 as DashboardHeroProps, DateInput, DatePicker, type DateRange, DateRangeInput, DateRangePicker, type DateRangePreset, DiagramSkeleton, type DiffChunk, type DiffInformation, type DiffRow, DiffType, DiffView, DotsLoader, DropdownMenu, EmptyConfigurationActionCard, EmptySearchContent, EmptyState, type RootProps$3 as EmptyStateProps, type Variant$1 as EmptyStateVariant, ErrorState, type RootProps$4 as ErrorStateProps, type Variant$2 as ErrorStateVariant, ExportMenu, ExportMenuItem, FileDownloadChip, FileUpload, type FileUploadAccept, type FileUploadRejection, type FileUploadRejectionCode, FormGroup, FullScreenModal, FullScreenModalBody, FullScreenModalHeader, GoogleButton, HINT_UNDERLINE_CLASS_NAME, HelpBlock, HoverCard, InlineStepDetail, type Props$2 as InlineStepDetailProps, InlineStepGroup, type Props$3 as InlineStepGroupProps, InlineStepLabel, type Props$4 as InlineStepLabelProps, type Variant$3 as InlineStepLabelVariant, InputGroup, Kbd, Label, type LineInformation, Link, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX, Markdown, MarkdownTable, MarkedText, type MergeConflict, MessageBubble, MicrosoftButton, Modal, MultiActionButtonGroup, MultiCombobox, MultiComboboxField, Navbar, NumberInput, OtpInput, type RootProps$5 as OtpInputProps, type OtpInputRenderSlotProps, PROMPT_INPUT_CONTAINER, PageHeader, PageLayout, PageToolbar, Pagination, PaneHeader, type PanelImperativeHandle, PanelWithDetails, PasswordInput, PlanApproval, type PlanApprovalProps, type PlanApprovalStatus, PlanRewritingIndicator, type PlanRewritingIndicatorProps, Popconfirm, Popover, Progress, type PromptCommand, PromptInput, Props$5 as Props, Question, type QuestionAnswers, QuestionBlock, type Props$6 as QuestionBlockProps, type QuestionOption, type Props$7 as QuestionProps, type QuestionStep, REGEXP_ONLY_CHARS, REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS, RadioGroup, type RadiusSize, ResizableHandle, ResizablePanel, ResizablePanelGroup, ResolvedColorScheme, ScrollArea, ScrollBar, Search, SearchForm, SearchInput, SearchInputWithNavigation, SectionNav, type SectionNavGroup, type SectionNavItem, type SectionNavItemRenderProps, Select, SelectItem, SelectItemGroup, SelectProps, Separator, type ServerFieldError, Sheet, type SideInformation, Sidebar, type SidebarMode, SidebarProvider, type SidebarSide, type SidebarSlot, Skeleton, SkeletonList, Slider, Slot, SplitButton, SpotlightBackdrop, SpotlightTarget, StatCard, StatCardGrid, type Props$8 as StatCardGridProps, type RootProps$6 as StatCardProps, type TrendDirection as StatCardTrendDirection, type TrendProps as StatCardTrendProps, type StepStatus, Stepper, type StepperOrientation, SuggestedPrompt, Switch, Table, type TableSortDirection, Tabs, TabsContent, TargetRect, TextInput, Textarea, Theme, ThemeProvider, ThemeScope, ThinkingIndicator, type ThinkingIndicatorProps, ThumbTooltipFn, TimeInput, TimePicker, Timeline, type ToastOptions, Toaster, Toggle, ToggleGroup, Tokens, ToolCallApproval, type ToolCallApprovalProps, type ToolCallApprovalStatus, ToolCallChip, type ToolCallChipProps, type ToolCallState, type ToolCallStatus, ToolCallStatusHeader, type Props$9 as ToolCallStatusHeaderProps, Tooltip, type Props$10 as TooltipProps, TooltipProvider, type Trigger, Truncated, UsageBar, UsageStats, UsageStatsRing, UseAutosizeInputOptions, UseAutosizeInputReturn, type ValidityState, type WithAccessibleName, type WordInformation, Workbench, type WorkbenchState, ZoomableSvg, agnes, appShellSlotSelector, argoVariants, brandSchema, channelsToHex, clampPercentage, cn, computeDiffRows, computeLineInformation, contrastRatio, copyToClipboard, defaultFilter, exampleCustomer, filterByWords, findLiteralMatches, findMentionToken, findSlashToken, formatPercentage, forwardAccessibleName, getChatInlineIconName, harbor, hasLiteralMatch, hexToChannels, isMac, kbdVariants, keboola, keboolaLegacySidebar, keys, matchByWords, mergeRefs, namedLabel, setServerFieldErrors, setSubmitError, svgToPngBlob, tableAriaSort, toSvgFileContent, toast, useAppForm, useArgoDesign, useAutosizeInput, useCommandState, useDefaultLayout, useFileDropTarget, useFileUploadRejections, useMergeDiff, useNotification, useOptionalSidebar, useScrollbarPosition, useSidebar, useStableCallback, useTargetRect, useTheme, useThemeScopeContainer, useWorkbench, wcagLevel, withBlankValues, withForm };
7366
+ export { Alert, AlertModal, AnswerActions, AnswerSummary, type AnswerItem as AnswerSummaryItem, type Props as AnswerSummaryProps, type Variant as AnswerSummaryVariant, AnswerVote, AppShell, type AppShellHeaderSpan, type AppShellSlot, ArgoDesignContext, AuthLayout, type RootProps as AuthLayoutProps, AutoSaveTextarea, Avatar, BLANK_VALUES, Badge, type Brand, BrandEditor, type BrandEditorProps, BrandId, BrandLogo, Breadcrumb, Button, ButtonGroup, ButtonInline, Calendar, type CalendarProps, Card, type ChangeClassification, ChartPanel, type RootProps$1 as ChartPanelProps, ChatInlineIcon, Checkbox, ChipEditor, type Props$1 as ChipEditorProps, Clipboard, ClipboardButton, ClipboardInline, Collapsible, CollapsiblePanel, CollapsibleStepHeader, ColorInput, ColorModeSwitch, ColorScheme, type ColorSlot, Combobox, ComboboxField, Command, CommandGroup, CommandInput, CommandItem, CommandList, ConflictStatusIndicator, CopyField, DEFAULT_COLOR_SCHEME, DEFAULT_FALLBACK_FONT, DEFAULT_FONT_OPTIONS, DEFAULT_BRAND_ID as DEFAULT_KEBOOLA_BRAND_ID, DEFAULT_WORKBENCH_BAR_HEIGHT_IN_REM, DEFAULT_WORKBENCH_PANEL_HEIGHT_IN_PX, DIAGRAM_LANGUAGES, DashboardHero, type RootProps$2 as DashboardHeroProps, DateInput, DatePicker, type DateRange, DateRangeInput, DateRangePicker, type DateRangePreset, DiagramSkeleton, type DiffChunk, type DiffInformation, type DiffRow, DiffType, DiffView, DotsLoader, DropdownMenu, EmptyConfigurationActionCard, EmptySearchContent, EmptyState, type RootProps$3 as EmptyStateProps, type Variant$1 as EmptyStateVariant, ErrorState, type RootProps$4 as ErrorStateProps, type Variant$2 as ErrorStateVariant, ExportMenu, ExportMenuItem, FileDownloadChip, FileUpload, type FileUploadAccept, type FileUploadRejection, type FileUploadRejectionCode, FormGroup, FullScreenModal, FullScreenModalBody, FullScreenModalHeader, GoogleButton, HINT_UNDERLINE_CLASS_NAME, HelpBlock, HoverCard, InlineStepDetail, type Props$2 as InlineStepDetailProps, InlineStepGroup, type Props$3 as InlineStepGroupProps, InlineStepLabel, type Props$4 as InlineStepLabelProps, type Variant$3 as InlineStepLabelVariant, InputGroup, Kbd, Label, type LineInformation, Link, MAX_DIGIT_HOTKEY, MIN_WORKBENCH_PANEL_HEIGHT_IN_PX, Markdown, MarkdownTable, MarkedText, type MergeConflict, MessageBubble, MicrosoftButton, Modal, MultiActionButtonGroup, MultiCombobox, MultiComboboxField, Navbar, NumberInput, OtpInput, type RootProps$5 as OtpInputProps, type OtpInputRenderSlotProps, PROMPT_INPUT_CONTAINER, PageHeader, PageLayout, PageToolbar, Pagination, PaneHeader, type PanelImperativeHandle, PanelWithDetails, PasswordInput, PlanApproval, type PlanApprovalProps, type PlanApprovalStatus, PlanRewritingIndicator, type PlanRewritingIndicatorProps, Popconfirm, Popover, Progress, type PromptCommand, PromptInput, Props$5 as Props, Question, type QuestionAnswers, QuestionBlock, type Props$6 as QuestionBlockProps, type QuestionOption, type Props$7 as QuestionProps, type QuestionStep, REGEXP_ONLY_CHARS, REGEXP_ONLY_DIGITS, REGEXP_ONLY_DIGITS_AND_CHARS, RadioGroup, type RadiusSize, ResizableHandle, ResizablePanel, ResizablePanelGroup, ResolvedColorScheme, ScrollArea, ScrollBar, Search, SearchForm, SearchInput, SearchInputWithNavigation, SectionNav, type SectionNavGroup, type SectionNavItem, type SectionNavItemRenderProps, Select, SelectItem, SelectItemGroup, SelectProps, Separator, type ServerFieldError, Sheet, type SideInformation, Sidebar, type SidebarMode, SidebarProvider, type SidebarSide, type SidebarSlot, Skeleton, SkeletonList, Slider, Slot, SplitButton, SpotlightBackdrop, SpotlightTarget, StatCard, StatCardGrid, type Props$8 as StatCardGridProps, type RootProps$6 as StatCardProps, type TrendDirection as StatCardTrendDirection, type TrendProps as StatCardTrendProps, type StepStatus, Stepper, type StepperOrientation, SuggestedPrompt, Switch, Table, type TableSortDirection, Tabs, TabsContent, TargetRect, TextInput, Textarea, Theme, ThemeProvider, ThemeScope, ThinkingIndicator, type ThinkingIndicatorProps, ThumbTooltipFn, TimeInput, TimePicker, Timeline, type ToastOptions, Toaster, Toggle, ToggleGroup, Tokens, ToolCallApproval, type ToolCallApprovalProps, type ToolCallApprovalStatus, ToolCallChip, type ToolCallChipProps, type ToolCallState, type ToolCallStatus, ToolCallStatusHeader, type Props$9 as ToolCallStatusHeaderProps, Tooltip, type Props$10 as TooltipProps, TooltipProvider, type Trigger, Truncated, UsageBar, UsageStats, UsageStatsRing, UseAutosizeInputOptions, UseAutosizeInputReturn, type ValidityState, type WithAccessibleName, type WordInformation, Workbench, type WorkbenchState, ZoomableSvg, agnes, appShellSlotSelector, argoVariants, brandSchema, channelsToHex, clampPercentage, cn, computeDiffRows, computeLineInformation, contrastRatio, copyToClipboard, defaultFilter, digitFromKeyCode, exampleCustomer, filterByWords, findLiteralMatches, findMentionToken, findSlashToken, formatPercentage, forwardAccessibleName, getChatInlineIconName, harbor, hasLiteralMatch, hexToChannels, isMac, kbdVariants, keboola, keboolaLegacySidebar, keys, matchByWords, mergeRefs, namedLabel, setServerFieldErrors, setSubmitError, svgToPngBlob, tableAriaSort, toSvgFileContent, toast, useAltDigitHotkey, useAppForm, useArgoDesign, useAutosizeInput, useCommandState, useDefaultLayout, useFileDropTarget, useFileUploadRejections, useMergeDiff, useNotification, useOptionalSidebar, useScrollbarPosition, useSidebar, useStableCallback, useTargetRect, useTheme, useThemeScopeContainer, useWorkbench, wcagLevel, withBlankValues, withForm };
7333
7367
  //# sourceMappingURL=index.d.ts.map