@aster-ui/prefixed 0.12.86 → 0.12.88

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,29 +1,29 @@
1
1
  import { jsx as N } from "react/jsx-runtime";
2
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 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
- import { indentOnInput as Y, syntaxHighlighting as Z, defaultHighlightStyle as tt, foldKeymap as et, foldGutter as ot, bracketMatching as rt } from "@codemirror/language";
6
- import { history as it, defaultKeymap as nt, historyKeymap as ct, indentWithTab as st } from "@codemirror/commands";
7
- import { highlightSelectionMatches as lt, searchKeymap as at } from "@codemirror/search";
8
- import { closeBracketsKeymap as ut, completionKeymap as mt, closeBrackets as ft, autocompletion as pt } from "@codemirror/autocomplete";
9
- import { lintKeymap as ht } from "@codemirror/lint";
4
+ import { EditorView as t, 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
+ import { indentOnInput as Y, syntaxHighlighting as Z, defaultHighlightStyle as ee, foldKeymap as te, foldGutter as oe, bracketMatching as re } from "@codemirror/language";
6
+ import { history as ie, defaultKeymap as ne, historyKeymap as ce, indentWithTab as se } from "@codemirror/commands";
7
+ import { highlightSelectionMatches as le, searchKeymap as ae } from "@codemirror/search";
8
+ import { closeBracketsKeymap as ue, completionKeymap as me, closeBrackets as fe, autocompletion as pe } from "@codemirror/autocomplete";
9
+ import { lintKeymap as he } from "@codemirror/lint";
10
10
  import { javascript as s } from "@codemirror/lang-javascript";
11
- import { python as dt } from "@codemirror/lang-python";
12
- import { html as gt } from "@codemirror/lang-html";
13
- import { css as bt } from "@codemirror/lang-css";
14
- import { json as yt } from "@codemirror/lang-json";
15
- import { markdown as vt } from "@codemirror/lang-markdown";
16
- import { sql as St } from "@codemirror/lang-sql";
17
- import { xml as kt } from "@codemirror/lang-xml";
18
- import { useConfig as xt } from "../providers/ConfigProvider.js";
19
- const Ct = {
11
+ import { python as de } from "@codemirror/lang-python";
12
+ import { html as ge } from "@codemirror/lang-html";
13
+ import { css as be } from "@codemirror/lang-css";
14
+ import { json as ve } from "@codemirror/lang-json";
15
+ import { markdown as ye } from "@codemirror/lang-markdown";
16
+ import { sql as Se } from "@codemirror/lang-sql";
17
+ import { xml as ke } from "@codemirror/lang-xml";
18
+ import { useConfig as xe } from "../providers/ConfigProvider.js";
19
+ const Ce = {
20
20
  xs: { fontSize: "11px", lineHeight: "1.4" },
21
21
  sm: { fontSize: "12px", lineHeight: "1.5" },
22
22
  md: { fontSize: "14px", lineHeight: "1.6" },
23
23
  lg: { fontSize: "16px", lineHeight: "1.6" },
24
24
  xl: { fontSize: "18px", lineHeight: "1.7" }
25
25
  };
26
- function zt(o) {
26
+ function we(o) {
27
27
  switch (o) {
28
28
  case "javascript":
29
29
  return s();
@@ -34,24 +34,24 @@ function zt(o) {
34
34
  case "tsx":
35
35
  return s({ jsx: !0, typescript: !0 });
36
36
  case "python":
37
- return dt();
37
+ return de();
38
38
  case "html":
39
- return gt();
39
+ return ge();
40
40
  case "css":
41
- return bt();
41
+ return be();
42
42
  case "json":
43
- return yt();
43
+ return ve();
44
44
  case "markdown":
45
- return vt();
45
+ return ye();
46
46
  case "sql":
47
- return St();
47
+ return Se();
48
48
  case "xml":
49
- return kt();
49
+ return ke();
50
50
  default:
51
51
  return null;
52
52
  }
53
53
  }
54
- const wt = e.theme({
54
+ const ze = t.theme({
55
55
  "&": {
56
56
  backgroundColor: "oklch(var(--b1))",
57
57
  color: "oklch(var(--bc))"
@@ -90,19 +90,19 @@ const wt = e.theme({
90
90
  color: "oklch(var(--bc) / 0.4)",
91
91
  fontStyle: "italic"
92
92
  }
93
- }), jt = O(
93
+ }), je = O(
94
94
  ({
95
95
  value: o = "",
96
96
  onChange: l,
97
- language: y = "plaintext",
97
+ language: v = "plaintext",
98
98
  placeholder: i,
99
- readOnly: v = !1,
99
+ readOnly: y = !1,
100
100
  autoFocus: S = !1,
101
101
  lineNumbers: k = !0,
102
102
  foldGutter: x = !0,
103
103
  highlightActiveLine: C = !0,
104
- bracketMatching: z = !0,
105
- closeBrackets: w = !0,
104
+ bracketMatching: w = !0,
105
+ closeBrackets: z = !0,
106
106
  autocompletion: j = !0,
107
107
  indentWithTab: E = !0,
108
108
  minHeight: a = 200,
@@ -111,41 +111,41 @@ const wt = e.theme({
111
111
  bordered: G = !0,
112
112
  extensions: H = [],
113
113
  onEditorReady: u,
114
- className: B = "",
115
- "data-testid": q = "code-editor",
116
- ...A
117
- }, T) => {
118
- const { componentSize: V } = xt(), K = $ ?? V ?? "md", m = d(null), f = d(null), p = d(l);
114
+ className: _ = "",
115
+ "data-testid": B = "code-editor",
116
+ ...q
117
+ }, A) => {
118
+ const { componentSize: T } = xe(), K = $ ?? T ?? "md", m = d(null), f = d(null), p = d(l);
119
119
  g(() => {
120
120
  p.current = l;
121
121
  }, [l]), g(() => {
122
122
  if (!m.current) return;
123
- const t = [
124
- wt,
123
+ const e = [
124
+ ze,
125
125
  W(),
126
- it(),
126
+ ie(),
127
127
  D(),
128
128
  I(),
129
129
  b.allowMultipleSelections.of(!0),
130
130
  Y(),
131
- Z(tt, { fallback: !0 }),
131
+ Z(ee, { fallback: !0 }),
132
132
  J(),
133
133
  P(),
134
- lt(),
134
+ le(),
135
135
  R.of([
136
- ...ut,
137
- ...nt,
138
- ...at,
139
- ...ct,
140
- ...et,
141
- ...mt,
142
- ...ht
136
+ ...ue,
137
+ ...ne,
138
+ ...ae,
139
+ ...ce,
140
+ ...te,
141
+ ...me,
142
+ ...he
143
143
  ])
144
144
  ];
145
- k && t.push(Q()), x && t.push(ot()), C && (t.push(U()), t.push(X())), z && t.push(rt()), w && t.push(ft()), j && t.push(pt()), E && t.push(R.of([st]));
146
- const r = zt(y);
147
- r && t.push(r), i && (t.push(e.contentAttributes.of({ "aria-placeholder": i })), t.push(
148
- e.theme({
145
+ k && e.push(Q()), x && e.push(oe()), C && (e.push(U()), e.push(X())), w && e.push(re()), z && e.push(fe()), j && e.push(pe()), E && e.push(R.of([se]));
146
+ const r = we(v);
147
+ r && e.push(r), i && (e.push(t.contentAttributes.of({ "aria-placeholder": i })), e.push(
148
+ t.theme({
149
149
  ".cm-content:has(.cm-line:only-child:empty)::before": {
150
150
  content: `"${i}"`,
151
151
  position: "absolute",
@@ -154,14 +154,14 @@ const wt = e.theme({
154
154
  pointerEvents: "none"
155
155
  }
156
156
  })
157
- )), v && (t.push(b.readOnly.of(!0)), t.push(e.editable.of(!1))), t.push(
158
- e.updateListener.of((M) => {
157
+ )), y && (e.push(b.readOnly.of(!0)), e.push(t.editable.of(!1))), e.push(
158
+ t.updateListener.of((M) => {
159
159
  M.docChanged && p.current && p.current(M.state.doc.toString());
160
160
  })
161
161
  );
162
- const h = Ct[K];
163
- t.push(
164
- e.theme({
162
+ const h = Ce[K];
163
+ e.push(
164
+ t.theme({
165
165
  ".cm-content": {
166
166
  fontSize: h.fontSize,
167
167
  lineHeight: h.lineHeight
@@ -170,11 +170,11 @@ const wt = e.theme({
170
170
  fontSize: h.fontSize
171
171
  }
172
172
  })
173
- ), t.push(...H);
173
+ ), e.push(...H);
174
174
  const F = b.create({
175
175
  doc: o,
176
- extensions: t
177
- }), c = new e({
176
+ extensions: e
177
+ }), c = new t({
178
178
  state: F,
179
179
  parent: m.current
180
180
  });
@@ -182,14 +182,14 @@ const wt = e.theme({
182
182
  c.destroy(), f.current = null;
183
183
  };
184
184
  }, [
185
- y,
186
- i,
187
185
  v,
186
+ i,
187
+ y,
188
188
  k,
189
189
  x,
190
190
  C,
191
- z,
192
191
  w,
192
+ z,
193
193
  j,
194
194
  E,
195
195
  K,
@@ -197,10 +197,10 @@ const wt = e.theme({
197
197
  H,
198
198
  u
199
199
  ]), g(() => {
200
- const t = f.current;
201
- if (!t) return;
202
- const r = t.state.doc.toString();
203
- o !== r && t.dispatch({
200
+ const e = f.current;
201
+ if (!e) return;
202
+ const r = e.state.doc.toString();
203
+ o !== r && e.dispatch({
204
204
  changes: {
205
205
  from: 0,
206
206
  to: r.length,
@@ -208,25 +208,25 @@ const wt = e.theme({
208
208
  }
209
209
  });
210
210
  }, [o]);
211
- const _ = typeof a == "number" ? `${a}px` : a, L = n ? typeof n == "number" ? `${n}px` : n : void 0;
211
+ const V = 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
  {
215
- ref: T,
215
+ ref: A,
216
216
  className: `
217
217
  bg-base-100 rounded-lg overflow-hidden
218
218
  ${G ? "border border-base-300" : ""}
219
- ${B}
219
+ ${_}
220
220
  `,
221
- "data-testid": q,
222
- ...A,
221
+ "data-testid": B,
222
+ ...q,
223
223
  children: /* @__PURE__ */ N(
224
224
  "div",
225
225
  {
226
226
  ref: m,
227
- className: "h-full [&_.cm-editor]:outline-none [&_.cm-editor]:h-full",
227
+ className: "h-full [&_.cm-editor]:outline-none [&_.cm-editor]:h-full [&_.cm-editor]:!overflow-hidden [&_.cm-scroller]:!overflow-auto",
228
228
  style: {
229
- minHeight: _,
229
+ minHeight: V,
230
230
  maxHeight: L,
231
231
  overflow: L ? "auto" : void 0
232
232
  }
@@ -236,9 +236,9 @@ const wt = e.theme({
236
236
  );
237
237
  }
238
238
  );
239
- jt.displayName = "CodeEditor";
239
+ je.displayName = "CodeEditor";
240
240
  export {
241
- jt as CodeEditor,
242
- jt as default
241
+ je as CodeEditor,
242
+ je as default
243
243
  };
244
244
  //# sourceMappingURL=CodeEditor.js.map
@@ -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=\"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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"}
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 [&_.cm-editor]:!overflow-hidden [&_.cm-scroller]:!overflow-auto\"\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,18 +1,19 @@
1
1
  import { default as React } from 'react';
2
2
  export interface ContextMenuItem {
3
3
  key: string;
4
- label: React.ReactNode;
4
+ label?: React.ReactNode;
5
5
  icon?: React.ReactNode;
6
6
  disabled?: boolean;
7
7
  danger?: boolean;
8
8
  divider?: boolean;
9
9
  children?: ContextMenuItem[];
10
+ 'data-testid'?: string;
10
11
  }
11
12
  export interface ContextMenuProps {
12
- /** Element that triggers the context menu on right-click */
13
+ /** Element that triggers the context menu on right-click (first child) */
13
14
  children: React.ReactNode;
14
- /** Menu items (data-driven pattern) */
15
- items?: ContextMenuItem[];
15
+ /** Menu items (data-driven pattern). Can be a static array or a function that receives the mouse event for dynamic items. */
16
+ items?: ContextMenuItem[] | ((e: React.MouseEvent) => ContextMenuItem[]);
16
17
  /** Callback when an item is selected */
17
18
  onSelect?: (key: string) => void;
18
19
  /** Whether the context menu is disabled */