@aster-ui/prefixed 0.12.85 → 0.12.86
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.
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as N } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef as
|
|
2
|
+
import { forwardRef as O, useRef as d, useEffect as g } from "react";
|
|
3
3
|
import { EditorState as b } from "@codemirror/state";
|
|
4
|
-
import { EditorView as e, highlightSpecialChars as
|
|
4
|
+
import { EditorView as e, highlightSpecialChars as W, drawSelection as D, dropCursor as I, rectangularSelection as J, crosshairCursor as P, keymap as R, lineNumbers as Q, highlightActiveLine as U, highlightActiveLineGutter as X } from "@codemirror/view";
|
|
5
5
|
import { indentOnInput as Y, syntaxHighlighting as Z, defaultHighlightStyle as tt, foldKeymap as et, foldGutter as ot, bracketMatching as rt } from "@codemirror/language";
|
|
6
6
|
import { history as it, defaultKeymap as nt, historyKeymap as ct, indentWithTab as st } from "@codemirror/commands";
|
|
7
7
|
import { highlightSelectionMatches as lt, searchKeymap as at } from "@codemirror/search";
|
|
@@ -90,7 +90,7 @@ const wt = e.theme({
|
|
|
90
90
|
color: "oklch(var(--bc) / 0.4)",
|
|
91
91
|
fontStyle: "italic"
|
|
92
92
|
}
|
|
93
|
-
}), jt =
|
|
93
|
+
}), jt = O(
|
|
94
94
|
({
|
|
95
95
|
value: o = "",
|
|
96
96
|
onChange: l,
|
|
@@ -122,7 +122,7 @@ const wt = e.theme({
|
|
|
122
122
|
if (!m.current) return;
|
|
123
123
|
const t = [
|
|
124
124
|
wt,
|
|
125
|
-
|
|
125
|
+
W(),
|
|
126
126
|
it(),
|
|
127
127
|
D(),
|
|
128
128
|
I(),
|
|
@@ -171,11 +171,11 @@ const wt = e.theme({
|
|
|
171
171
|
}
|
|
172
172
|
})
|
|
173
173
|
), t.push(...H);
|
|
174
|
-
const
|
|
174
|
+
const F = b.create({
|
|
175
175
|
doc: o,
|
|
176
176
|
extensions: t
|
|
177
177
|
}), c = new e({
|
|
178
|
-
state:
|
|
178
|
+
state: F,
|
|
179
179
|
parent: m.current
|
|
180
180
|
});
|
|
181
181
|
return f.current = c, S && c.focus(), u && u(c), () => {
|
|
@@ -208,7 +208,7 @@ const wt = e.theme({
|
|
|
208
208
|
}
|
|
209
209
|
});
|
|
210
210
|
}, [o]);
|
|
211
|
-
const
|
|
211
|
+
const _ = typeof a == "number" ? `${a}px` : a, L = n ? typeof n == "number" ? `${n}px` : n : void 0;
|
|
212
212
|
return /* @__PURE__ */ N(
|
|
213
213
|
"div",
|
|
214
214
|
{
|
|
@@ -224,9 +224,9 @@ const wt = e.theme({
|
|
|
224
224
|
"div",
|
|
225
225
|
{
|
|
226
226
|
ref: m,
|
|
227
|
-
className: "[&_.cm-editor]:outline-none",
|
|
227
|
+
className: "h-full [&_.cm-editor]:outline-none [&_.cm-editor]:h-full",
|
|
228
228
|
style: {
|
|
229
|
-
minHeight:
|
|
229
|
+
minHeight: _,
|
|
230
230
|
maxHeight: L,
|
|
231
231
|
overflow: L ? "auto" : void 0
|
|
232
232
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeEditor.js","sources":["../../src/components/CodeEditor.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useRef } from 'react'\nimport { EditorState, type Extension } from '@codemirror/state'\nimport { EditorView, keymap, lineNumbers, highlightActiveLine, highlightActiveLineGutter, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightSpecialChars } from '@codemirror/view'\nimport { defaultHighlightStyle, syntaxHighlighting, indentOnInput, bracketMatching, foldGutter, foldKeymap } from '@codemirror/language'\nimport { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands'\nimport { searchKeymap, highlightSelectionMatches } from '@codemirror/search'\nimport { autocompletion, completionKeymap, closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete'\nimport { lintKeymap } from '@codemirror/lint'\nimport { javascript } from '@codemirror/lang-javascript'\nimport { python } from '@codemirror/lang-python'\nimport { html } from '@codemirror/lang-html'\nimport { css } from '@codemirror/lang-css'\nimport { json } from '@codemirror/lang-json'\nimport { markdown } from '@codemirror/lang-markdown'\nimport { sql } from '@codemirror/lang-sql'\nimport { xml } from '@codemirror/lang-xml'\nimport { useConfig } from '../providers/ConfigProvider'\n\nexport type CodeEditorLanguage =\n | 'javascript'\n | 'typescript'\n | 'jsx'\n | 'tsx'\n | 'python'\n | 'html'\n | 'css'\n | 'json'\n | 'markdown'\n | 'sql'\n | 'xml'\n | 'plaintext'\n\nexport interface CodeEditorProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Code content */\n value?: string\n /** Callback when content changes */\n onChange?: (value: string) => void\n /** Programming language for syntax highlighting */\n language?: CodeEditorLanguage\n /** Placeholder text when empty */\n placeholder?: string\n /** Make editor read-only */\n readOnly?: boolean\n /** Auto focus on mount */\n autoFocus?: boolean\n /** Show line numbers */\n lineNumbers?: boolean\n /** Enable code folding */\n foldGutter?: boolean\n /** Highlight active line */\n highlightActiveLine?: boolean\n /** Enable bracket matching */\n bracketMatching?: boolean\n /** Enable auto-closing brackets */\n closeBrackets?: boolean\n /** Enable autocompletion */\n autocompletion?: boolean\n /** Allow tab key for indentation */\n indentWithTab?: boolean\n /** Minimum height of the editor */\n minHeight?: string | number\n /** Maximum height of the editor (enables scrolling) */\n maxHeight?: string | number\n /** Editor size variant */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n /** Show border around editor */\n bordered?: boolean\n /** Additional CodeMirror extensions */\n extensions?: Extension[]\n /** Callback with editor view instance */\n onEditorReady?: (view: EditorView) => void\n 'data-testid'?: string\n}\n\nconst sizeClasses = {\n xs: { fontSize: '11px', lineHeight: '1.4' },\n sm: { fontSize: '12px', lineHeight: '1.5' },\n md: { fontSize: '14px', lineHeight: '1.6' },\n lg: { fontSize: '16px', lineHeight: '1.6' },\n xl: { fontSize: '18px', lineHeight: '1.7' },\n}\n\nfunction getLanguageExtension(language: CodeEditorLanguage): Extension | null {\n switch (language) {\n case 'javascript':\n return javascript()\n case 'typescript':\n return javascript({ typescript: true })\n case 'jsx':\n return javascript({ jsx: true })\n case 'tsx':\n return javascript({ jsx: true, typescript: true })\n case 'python':\n return python()\n case 'html':\n return html()\n case 'css':\n return css()\n case 'json':\n return json()\n case 'markdown':\n return markdown()\n case 'sql':\n return sql()\n case 'xml':\n return xml()\n case 'plaintext':\n default:\n return null\n }\n}\n\nconst baseTheme = EditorView.theme({\n '&': {\n backgroundColor: 'oklch(var(--b1))',\n color: 'oklch(var(--bc))',\n },\n '.cm-content': {\n caretColor: 'oklch(var(--bc))',\n fontFamily: 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace',\n },\n '.cm-cursor, .cm-dropCursor': {\n borderLeftColor: 'oklch(var(--bc))',\n },\n '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {\n backgroundColor: 'oklch(var(--p) / 0.2)',\n },\n '.cm-activeLine': {\n backgroundColor: 'oklch(var(--bc) / 0.05)',\n },\n '.cm-activeLineGutter': {\n backgroundColor: 'oklch(var(--bc) / 0.05)',\n },\n '.cm-gutters': {\n backgroundColor: 'oklch(var(--b2))',\n color: 'oklch(var(--bc) / 0.5)',\n borderRight: '1px solid oklch(var(--b3))',\n },\n '.cm-lineNumbers .cm-gutterElement': {\n padding: '0 8px 0 16px',\n },\n '.cm-foldGutter .cm-gutterElement': {\n padding: '0 4px',\n },\n '.cm-scroller': {\n overflow: 'auto',\n },\n '.cm-placeholder': {\n color: 'oklch(var(--bc) / 0.4)',\n fontStyle: 'italic',\n },\n})\n\nexport const CodeEditor = forwardRef<HTMLDivElement, CodeEditorProps>(\n (\n {\n value = '',\n onChange,\n language = 'plaintext',\n placeholder,\n readOnly = false,\n autoFocus = false,\n lineNumbers: showLineNumbers = true,\n foldGutter: showFoldGutter = true,\n highlightActiveLine: showHighlightActiveLine = true,\n bracketMatching: enableBracketMatching = true,\n closeBrackets: enableCloseBrackets = true,\n autocompletion: enableAutocompletion = true,\n indentWithTab: enableIndentWithTab = true,\n minHeight = 200,\n maxHeight,\n size,\n bordered = true,\n extensions: additionalExtensions = [],\n onEditorReady,\n className = '',\n 'data-testid': testId = 'code-editor',\n ...rest\n },\n ref\n ) => {\n const { componentSize } = useConfig()\n const effectiveSize = size ?? componentSize ?? 'md'\n\n const containerRef = useRef<HTMLDivElement>(null)\n const viewRef = useRef<EditorView | null>(null)\n const onChangeRef = useRef(onChange)\n\n // Keep onChange ref updated\n useEffect(() => {\n onChangeRef.current = onChange\n }, [onChange])\n\n // Create and manage editor\n useEffect(() => {\n if (!containerRef.current) return\n\n const extensions: Extension[] = [\n baseTheme,\n highlightSpecialChars(),\n history(),\n drawSelection(),\n dropCursor(),\n EditorState.allowMultipleSelections.of(true),\n indentOnInput(),\n syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n rectangularSelection(),\n crosshairCursor(),\n highlightSelectionMatches(),\n keymap.of([\n ...closeBracketsKeymap,\n ...defaultKeymap,\n ...searchKeymap,\n ...historyKeymap,\n ...foldKeymap,\n ...completionKeymap,\n ...lintKeymap,\n ]),\n ]\n\n if (showLineNumbers) {\n extensions.push(lineNumbers())\n }\n\n if (showFoldGutter) {\n extensions.push(foldGutter())\n }\n\n if (showHighlightActiveLine) {\n extensions.push(highlightActiveLine())\n extensions.push(highlightActiveLineGutter())\n }\n\n if (enableBracketMatching) {\n extensions.push(bracketMatching())\n }\n\n if (enableCloseBrackets) {\n extensions.push(closeBrackets())\n }\n\n if (enableAutocompletion) {\n extensions.push(autocompletion())\n }\n\n if (enableIndentWithTab) {\n extensions.push(keymap.of([indentWithTab]))\n }\n\n const langExtension = getLanguageExtension(language)\n if (langExtension) {\n extensions.push(langExtension)\n }\n\n if (placeholder) {\n extensions.push(EditorView.contentAttributes.of({ 'aria-placeholder': placeholder }))\n extensions.push(\n EditorView.theme({\n '.cm-content:has(.cm-line:only-child:empty)::before': {\n content: `\"${placeholder}\"`,\n position: 'absolute',\n color: 'oklch(var(--bc) / 0.4)',\n fontStyle: 'italic',\n pointerEvents: 'none',\n },\n })\n )\n }\n\n if (readOnly) {\n extensions.push(EditorState.readOnly.of(true))\n extensions.push(EditorView.editable.of(false))\n }\n\n // Update listener\n extensions.push(\n EditorView.updateListener.of((update) => {\n if (update.docChanged && onChangeRef.current) {\n onChangeRef.current(update.state.doc.toString())\n }\n })\n )\n\n // Size styling\n const sizeStyle = sizeClasses[effectiveSize]\n extensions.push(\n EditorView.theme({\n '.cm-content': {\n fontSize: sizeStyle.fontSize,\n lineHeight: sizeStyle.lineHeight,\n },\n '.cm-gutters': {\n fontSize: sizeStyle.fontSize,\n },\n })\n )\n\n // Add user extensions\n extensions.push(...additionalExtensions)\n\n const state = EditorState.create({\n doc: value,\n extensions,\n })\n\n const view = new EditorView({\n state,\n parent: containerRef.current,\n })\n\n viewRef.current = view\n\n if (autoFocus) {\n view.focus()\n }\n\n if (onEditorReady) {\n onEditorReady(view)\n }\n\n return () => {\n view.destroy()\n viewRef.current = null\n }\n }, [\n language,\n placeholder,\n readOnly,\n showLineNumbers,\n showFoldGutter,\n showHighlightActiveLine,\n enableBracketMatching,\n enableCloseBrackets,\n enableAutocompletion,\n enableIndentWithTab,\n effectiveSize,\n autoFocus,\n additionalExtensions,\n onEditorReady,\n ])\n\n // Sync value prop changes\n useEffect(() => {\n const view = viewRef.current\n if (!view) return\n\n const currentValue = view.state.doc.toString()\n if (value !== currentValue) {\n view.dispatch({\n changes: {\n from: 0,\n to: currentValue.length,\n insert: value,\n },\n })\n }\n }, [value])\n\n const minHeightStyle = typeof minHeight === 'number' ? `${minHeight}px` : minHeight\n const maxHeightStyle = maxHeight\n ? typeof maxHeight === 'number'\n ? `${maxHeight}px`\n : maxHeight\n : undefined\n\n return (\n <div\n ref={ref}\n className={`\n bg-base-100 rounded-lg overflow-hidden\n ${bordered ? 'border border-base-300' : ''}\n ${className}\n `}\n data-testid={testId}\n {...rest}\n >\n <div\n ref={containerRef}\n className=\"[&_.cm-editor]:outline-none\"\n style={{\n minHeight: minHeightStyle,\n maxHeight: maxHeightStyle,\n overflow: maxHeightStyle ? 'auto' : undefined,\n }}\n />\n </div>\n )\n }\n)\n\nCodeEditor.displayName = 'CodeEditor'\n\nexport default CodeEditor\n"],"names":["sizeClasses","getLanguageExtension","language","javascript","python","html","css","json","markdown","sql","xml","baseTheme","EditorView","CodeEditor","forwardRef","value","onChange","placeholder","readOnly","autoFocus","showLineNumbers","showFoldGutter","showHighlightActiveLine","enableBracketMatching","enableCloseBrackets","enableAutocompletion","enableIndentWithTab","minHeight","maxHeight","size","bordered","additionalExtensions","onEditorReady","className","testId","rest","ref","componentSize","useConfig","effectiveSize","containerRef","useRef","viewRef","onChangeRef","useEffect","extensions","highlightSpecialChars","history","drawSelection","dropCursor","EditorState","indentOnInput","syntaxHighlighting","defaultHighlightStyle","rectangularSelection","crosshairCursor","highlightSelectionMatches","keymap","closeBracketsKeymap","defaultKeymap","searchKeymap","historyKeymap","foldKeymap","completionKeymap","lintKeymap","lineNumbers","foldGutter","highlightActiveLine","highlightActiveLineGutter","bracketMatching","closeBrackets","autocompletion","indentWithTab","langExtension","update","sizeStyle","state","view","currentValue","minHeightStyle","maxHeightStyle","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"CodeEditor.js","sources":["../../src/components/CodeEditor.tsx"],"sourcesContent":["import React, { forwardRef, useEffect, useRef } from 'react'\nimport { EditorState, type Extension } from '@codemirror/state'\nimport { EditorView, keymap, lineNumbers, highlightActiveLine, highlightActiveLineGutter, drawSelection, dropCursor, rectangularSelection, crosshairCursor, highlightSpecialChars } from '@codemirror/view'\nimport { defaultHighlightStyle, syntaxHighlighting, indentOnInput, bracketMatching, foldGutter, foldKeymap } from '@codemirror/language'\nimport { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands'\nimport { searchKeymap, highlightSelectionMatches } from '@codemirror/search'\nimport { autocompletion, completionKeymap, closeBrackets, closeBracketsKeymap } from '@codemirror/autocomplete'\nimport { lintKeymap } from '@codemirror/lint'\nimport { javascript } from '@codemirror/lang-javascript'\nimport { python } from '@codemirror/lang-python'\nimport { html } from '@codemirror/lang-html'\nimport { css } from '@codemirror/lang-css'\nimport { json } from '@codemirror/lang-json'\nimport { markdown } from '@codemirror/lang-markdown'\nimport { sql } from '@codemirror/lang-sql'\nimport { xml } from '@codemirror/lang-xml'\nimport { useConfig } from '../providers/ConfigProvider'\n\nexport type CodeEditorLanguage =\n | 'javascript'\n | 'typescript'\n | 'jsx'\n | 'tsx'\n | 'python'\n | 'html'\n | 'css'\n | 'json'\n | 'markdown'\n | 'sql'\n | 'xml'\n | 'plaintext'\n\nexport interface CodeEditorProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {\n /** Code content */\n value?: string\n /** Callback when content changes */\n onChange?: (value: string) => void\n /** Programming language for syntax highlighting */\n language?: CodeEditorLanguage\n /** Placeholder text when empty */\n placeholder?: string\n /** Make editor read-only */\n readOnly?: boolean\n /** Auto focus on mount */\n autoFocus?: boolean\n /** Show line numbers */\n lineNumbers?: boolean\n /** Enable code folding */\n foldGutter?: boolean\n /** Highlight active line */\n highlightActiveLine?: boolean\n /** Enable bracket matching */\n bracketMatching?: boolean\n /** Enable auto-closing brackets */\n closeBrackets?: boolean\n /** Enable autocompletion */\n autocompletion?: boolean\n /** Allow tab key for indentation */\n indentWithTab?: boolean\n /** Minimum height of the editor */\n minHeight?: string | number\n /** Maximum height of the editor (enables scrolling) */\n maxHeight?: string | number\n /** Editor size variant */\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'\n /** Show border around editor */\n bordered?: boolean\n /** Additional CodeMirror extensions */\n extensions?: Extension[]\n /** Callback with editor view instance */\n onEditorReady?: (view: EditorView) => void\n 'data-testid'?: string\n}\n\nconst sizeClasses = {\n xs: { fontSize: '11px', lineHeight: '1.4' },\n sm: { fontSize: '12px', lineHeight: '1.5' },\n md: { fontSize: '14px', lineHeight: '1.6' },\n lg: { fontSize: '16px', lineHeight: '1.6' },\n xl: { fontSize: '18px', lineHeight: '1.7' },\n}\n\nfunction getLanguageExtension(language: CodeEditorLanguage): Extension | null {\n switch (language) {\n case 'javascript':\n return javascript()\n case 'typescript':\n return javascript({ typescript: true })\n case 'jsx':\n return javascript({ jsx: true })\n case 'tsx':\n return javascript({ jsx: true, typescript: true })\n case 'python':\n return python()\n case 'html':\n return html()\n case 'css':\n return css()\n case 'json':\n return json()\n case 'markdown':\n return markdown()\n case 'sql':\n return sql()\n case 'xml':\n return xml()\n case 'plaintext':\n default:\n return null\n }\n}\n\nconst baseTheme = EditorView.theme({\n '&': {\n backgroundColor: 'oklch(var(--b1))',\n color: 'oklch(var(--bc))',\n },\n '.cm-content': {\n caretColor: 'oklch(var(--bc))',\n fontFamily: 'ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace',\n },\n '.cm-cursor, .cm-dropCursor': {\n borderLeftColor: 'oklch(var(--bc))',\n },\n '&.cm-focused .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection': {\n backgroundColor: 'oklch(var(--p) / 0.2)',\n },\n '.cm-activeLine': {\n backgroundColor: 'oklch(var(--bc) / 0.05)',\n },\n '.cm-activeLineGutter': {\n backgroundColor: 'oklch(var(--bc) / 0.05)',\n },\n '.cm-gutters': {\n backgroundColor: 'oklch(var(--b2))',\n color: 'oklch(var(--bc) / 0.5)',\n borderRight: '1px solid oklch(var(--b3))',\n },\n '.cm-lineNumbers .cm-gutterElement': {\n padding: '0 8px 0 16px',\n },\n '.cm-foldGutter .cm-gutterElement': {\n padding: '0 4px',\n },\n '.cm-scroller': {\n overflow: 'auto',\n },\n '.cm-placeholder': {\n color: 'oklch(var(--bc) / 0.4)',\n fontStyle: 'italic',\n },\n})\n\nexport const CodeEditor = forwardRef<HTMLDivElement, CodeEditorProps>(\n (\n {\n value = '',\n onChange,\n language = 'plaintext',\n placeholder,\n readOnly = false,\n autoFocus = false,\n lineNumbers: showLineNumbers = true,\n foldGutter: showFoldGutter = true,\n highlightActiveLine: showHighlightActiveLine = true,\n bracketMatching: enableBracketMatching = true,\n closeBrackets: enableCloseBrackets = true,\n autocompletion: enableAutocompletion = true,\n indentWithTab: enableIndentWithTab = true,\n minHeight = 200,\n maxHeight,\n size,\n bordered = true,\n extensions: additionalExtensions = [],\n onEditorReady,\n className = '',\n 'data-testid': testId = 'code-editor',\n ...rest\n },\n ref\n ) => {\n const { componentSize } = useConfig()\n const effectiveSize = size ?? componentSize ?? 'md'\n\n const containerRef = useRef<HTMLDivElement>(null)\n const viewRef = useRef<EditorView | null>(null)\n const onChangeRef = useRef(onChange)\n\n // Keep onChange ref updated\n useEffect(() => {\n onChangeRef.current = onChange\n }, [onChange])\n\n // Create and manage editor\n useEffect(() => {\n if (!containerRef.current) return\n\n const extensions: Extension[] = [\n baseTheme,\n highlightSpecialChars(),\n history(),\n drawSelection(),\n dropCursor(),\n EditorState.allowMultipleSelections.of(true),\n indentOnInput(),\n syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n rectangularSelection(),\n crosshairCursor(),\n highlightSelectionMatches(),\n keymap.of([\n ...closeBracketsKeymap,\n ...defaultKeymap,\n ...searchKeymap,\n ...historyKeymap,\n ...foldKeymap,\n ...completionKeymap,\n ...lintKeymap,\n ]),\n ]\n\n if (showLineNumbers) {\n extensions.push(lineNumbers())\n }\n\n if (showFoldGutter) {\n extensions.push(foldGutter())\n }\n\n if (showHighlightActiveLine) {\n extensions.push(highlightActiveLine())\n extensions.push(highlightActiveLineGutter())\n }\n\n if (enableBracketMatching) {\n extensions.push(bracketMatching())\n }\n\n if (enableCloseBrackets) {\n extensions.push(closeBrackets())\n }\n\n if (enableAutocompletion) {\n extensions.push(autocompletion())\n }\n\n if (enableIndentWithTab) {\n extensions.push(keymap.of([indentWithTab]))\n }\n\n const langExtension = getLanguageExtension(language)\n if (langExtension) {\n extensions.push(langExtension)\n }\n\n if (placeholder) {\n extensions.push(EditorView.contentAttributes.of({ 'aria-placeholder': placeholder }))\n extensions.push(\n EditorView.theme({\n '.cm-content:has(.cm-line:only-child:empty)::before': {\n content: `\"${placeholder}\"`,\n position: 'absolute',\n color: 'oklch(var(--bc) / 0.4)',\n fontStyle: 'italic',\n pointerEvents: 'none',\n },\n })\n )\n }\n\n if (readOnly) {\n extensions.push(EditorState.readOnly.of(true))\n extensions.push(EditorView.editable.of(false))\n }\n\n // Update listener\n extensions.push(\n EditorView.updateListener.of((update) => {\n if (update.docChanged && onChangeRef.current) {\n onChangeRef.current(update.state.doc.toString())\n }\n })\n )\n\n // Size styling\n const sizeStyle = sizeClasses[effectiveSize]\n extensions.push(\n EditorView.theme({\n '.cm-content': {\n fontSize: sizeStyle.fontSize,\n lineHeight: sizeStyle.lineHeight,\n },\n '.cm-gutters': {\n fontSize: sizeStyle.fontSize,\n },\n })\n )\n\n // Add user extensions\n extensions.push(...additionalExtensions)\n\n const state = EditorState.create({\n doc: value,\n extensions,\n })\n\n const view = new EditorView({\n state,\n parent: containerRef.current,\n })\n\n viewRef.current = view\n\n if (autoFocus) {\n view.focus()\n }\n\n if (onEditorReady) {\n onEditorReady(view)\n }\n\n return () => {\n view.destroy()\n viewRef.current = null\n }\n }, [\n language,\n placeholder,\n readOnly,\n showLineNumbers,\n showFoldGutter,\n showHighlightActiveLine,\n enableBracketMatching,\n enableCloseBrackets,\n enableAutocompletion,\n enableIndentWithTab,\n effectiveSize,\n autoFocus,\n additionalExtensions,\n onEditorReady,\n ])\n\n // Sync value prop changes\n useEffect(() => {\n const view = viewRef.current\n if (!view) return\n\n const currentValue = view.state.doc.toString()\n if (value !== currentValue) {\n view.dispatch({\n changes: {\n from: 0,\n to: currentValue.length,\n insert: value,\n },\n })\n }\n }, [value])\n\n const minHeightStyle = typeof minHeight === 'number' ? `${minHeight}px` : minHeight\n const maxHeightStyle = maxHeight\n ? typeof maxHeight === 'number'\n ? `${maxHeight}px`\n : maxHeight\n : undefined\n\n return (\n <div\n ref={ref}\n className={`\n bg-base-100 rounded-lg overflow-hidden\n ${bordered ? 'border border-base-300' : ''}\n ${className}\n `}\n data-testid={testId}\n {...rest}\n >\n <div\n ref={containerRef}\n className=\"h-full [&_.cm-editor]:outline-none [&_.cm-editor]:h-full\"\n style={{\n minHeight: minHeightStyle,\n maxHeight: maxHeightStyle,\n overflow: maxHeightStyle ? 'auto' : undefined,\n }}\n />\n </div>\n )\n }\n)\n\nCodeEditor.displayName = 'CodeEditor'\n\nexport default CodeEditor\n"],"names":["sizeClasses","getLanguageExtension","language","javascript","python","html","css","json","markdown","sql","xml","baseTheme","EditorView","CodeEditor","forwardRef","value","onChange","placeholder","readOnly","autoFocus","showLineNumbers","showFoldGutter","showHighlightActiveLine","enableBracketMatching","enableCloseBrackets","enableAutocompletion","enableIndentWithTab","minHeight","maxHeight","size","bordered","additionalExtensions","onEditorReady","className","testId","rest","ref","componentSize","useConfig","effectiveSize","containerRef","useRef","viewRef","onChangeRef","useEffect","extensions","highlightSpecialChars","history","drawSelection","dropCursor","EditorState","indentOnInput","syntaxHighlighting","defaultHighlightStyle","rectangularSelection","crosshairCursor","highlightSelectionMatches","keymap","closeBracketsKeymap","defaultKeymap","searchKeymap","historyKeymap","foldKeymap","completionKeymap","lintKeymap","lineNumbers","foldGutter","highlightActiveLine","highlightActiveLineGutter","bracketMatching","closeBrackets","autocompletion","indentWithTab","langExtension","update","sizeStyle","state","view","currentValue","minHeightStyle","maxHeightStyle","jsx"],"mappings":"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"}
|