@kingsimba/nc-ui 0.1.41 → 0.1.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -27
- package/dist/code-editor.cjs +36 -0
- package/dist/code-editor.cjs.map +1 -0
- package/dist/code-editor.d.ts +34 -0
- package/dist/code-editor.js +266 -0
- package/dist/code-editor.js.map +1 -0
- package/dist/index-BZJJwrMY.js +3089 -0
- package/dist/index-BZJJwrMY.js.map +1 -0
- package/dist/index-Isl3QL-U.cjs +47 -0
- package/dist/index-Isl3QL-U.cjs.map +1 -0
- package/dist/index.cjs +5 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +225 -225
- package/dist/index.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/yaml.cjs +111 -156
- package/dist/yaml.cjs.map +1 -1
- package/dist/yaml.js +1840 -4920
- package/dist/yaml.js.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -70,33 +70,34 @@ function MyComponent() {
|
|
|
70
70
|
|
|
71
71
|
nc-ui provides 23+ ready-to-use components. Click any component to see it in the interactive demo:
|
|
72
72
|
|
|
73
|
-
| Component | Description
|
|
74
|
-
| ---------------------------------------------------------------------------------------- |
|
|
75
|
-
| [ActivityIndicator](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=activity) | Loading spinner with size variants and overlay mode
|
|
76
|
-
| [Alert](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=alert) | Status banners with simple content, optional dismissal, and legacy code/text support
|
|
77
|
-
| [AppDialog](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=app-dialog) | Render any registered app inside a dialog overlay
|
|
78
|
-
| [Battery](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=battery) | Visual battery level indicator
|
|
79
|
-
| [Button](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=buttons) | Primary action button with variants, sizes, and loading states
|
|
80
|
-
| [ButtonGroup](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=button-group) | Segmented control for switching between predefined options
|
|
81
|
-
| [Checkbox](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=checkbox) | Toggle selection with indeterminate state support
|
|
82
|
-
| [CommonButtons](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=buttons-icon) | Pre-configured buttons (Close, Edit, Refresh, Trash)
|
|
83
|
-
| [ComboBox](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=combobox) | Searchable dropdown with autocomplete
|
|
84
|
-
| [
|
|
85
|
-
| [
|
|
86
|
-
| [
|
|
87
|
-
| [
|
|
88
|
-
| [
|
|
89
|
-
| [
|
|
90
|
-
| [
|
|
91
|
-
| [
|
|
92
|
-
| [
|
|
93
|
-
| [
|
|
94
|
-
| [
|
|
95
|
-
| [
|
|
96
|
-
| [
|
|
97
|
-
| [
|
|
98
|
-
| [
|
|
99
|
-
| [
|
|
73
|
+
| Component | Description |
|
|
74
|
+
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
|
|
75
|
+
| [ActivityIndicator](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=activity) | Loading spinner with size variants and overlay mode |
|
|
76
|
+
| [Alert](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=alert) | Status banners with simple content, optional dismissal, and legacy code/text support |
|
|
77
|
+
| [AppDialog](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=app-dialog) | Render any registered app inside a dialog overlay |
|
|
78
|
+
| [Battery](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=battery) | Visual battery level indicator |
|
|
79
|
+
| [Button](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=buttons) | Primary action button with variants, sizes, and loading states |
|
|
80
|
+
| [ButtonGroup](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=button-group) | Segmented control for switching between predefined options |
|
|
81
|
+
| [Checkbox](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=checkbox) | Toggle selection with indeterminate state support |
|
|
82
|
+
| [CommonButtons](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=buttons-icon) | Pre-configured buttons (Close, Edit, Refresh, Trash) |
|
|
83
|
+
| [ComboBox](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=combobox) | Searchable dropdown with autocomplete |
|
|
84
|
+
| [CodeEditor](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=code-editor) | Code editor with syntax highlighting and line numbers (import from `@kingsimba/nc-ui/code-editor`) |
|
|
85
|
+
| [ContextMenu](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=context-menu) | Right-click menu with customizable items |
|
|
86
|
+
| [CsvTextArea](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=csv-textarea) | Tab-separated text editor with per-column color highlighting |
|
|
87
|
+
| [Dialog](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=dialog) | Modal dialogs with header, footer, and action buttons |
|
|
88
|
+
| [Hyperlink](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=hyperlink) | Styled anchor/link component |
|
|
89
|
+
| [Icons](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=icons) | 50+ SVG icons (separate import path) |
|
|
90
|
+
| [Input](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=input) | Text input with validation states and prefix/suffix support |
|
|
91
|
+
| [ListGroup](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=list-group) | Grouped content sections built from `ListGroupItem` children |
|
|
92
|
+
| [MonthRangePicker](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=month-range) | Month range selector with validation (YY-M(M) or YYYY-M(M) format) |
|
|
93
|
+
| [MultiSelect](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=multi-select) | Multi-selection dropdown with tag display |
|
|
94
|
+
| [NavStack](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=nav-stack) | Stack-based navigation for mobile-style settings UIs |
|
|
95
|
+
| [Notification](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=notification) | Toast-style notifications with auto-dismiss and stacking |
|
|
96
|
+
| [NumberInput](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=number-input) | Numeric input with increment/decrement controls |
|
|
97
|
+
| [Slider](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=slider) | Range slider with value display |
|
|
98
|
+
| [Tabs](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=tabs) | Tabbed navigation component |
|
|
99
|
+
| [Toggle](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=toggle) | Switch/toggle with on/off states |
|
|
100
|
+
| [YamlTextArea](https://kingsimba.github.io/nc-ui/?app=ui-components&tab=yaml-textarea) | YAML editor with syntax highlighting and validation (import from `@kingsimba/nc-ui/yaml`) |
|
|
100
101
|
|
|
101
102
|
## App Framework
|
|
102
103
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("react/jsx-runtime"),s=require("react"),m=require("./index-Isl3QL-U.cjs");function A(n,a,o,t){if(!a)return{content:n,column:t+n.length};let r=t;return{content:Array.from(n,(d,c)=>{if(d===" ")return r++,e.jsx("span",{className:"nc-code-editor-whitespace","aria-hidden":"true",children:"·"},c);if(d===" "){const p=o-r%o;return r+=p,e.jsx("span",{className:"nc-code-editor-whitespace nc-code-editor-tab",style:{width:`${p}ch`},"aria-hidden":"true",children:"→"},c)}return r++,d}),column:r}}function H(n){var r;const a=(r=n.split(".").pop())==null?void 0:r.toLowerCase();if(!a)return;const o={ts:"typescript",tsx:"tsx",js:"javascript",jsx:"jsx",json:"json",yaml:"yaml",yml:"yaml",py:"python",rb:"ruby",rs:"rust",go:"go",java:"java",c:"c",cpp:"cpp",h:"c",hpp:"cpp",cs:"csharp",sh:"bash",bash:"bash",zsh:"bash",fish:"bash",md:"markdown",markdown:"markdown",html:"html",htm:"html",css:"css",scss:"scss",sql:"sql",xml:"xml",svg:"xml",toml:"toml",ini:"ini",cfg:"ini",conf:"ini",properties:"properties",env:"properties",nginx:"nginx",dockerfile:"docker",makefile:"makefile",cmake:"cmake",lua:"lua",php:"php",pl:"perl",pm:"perl",r:"r",swift:"swift",kt:"kotlin",scala:"scala",dart:"dart",graphql:"graphql",proto:"protobuf"};if(o[a])return o[a];const t=n.toLowerCase();if(o[t])return o[t]}function S({value:n,onChange:a,language:o,readOnly:t=!1,minHeight:r=100,maxHeight:x,lineNumbers:d=!0,showWhitespace:c=!1,tabSize:p=8,colorTheme:b="auto",className:R="",style:q={}}){const h=Number.isFinite(p)?Math.max(1,Math.floor(p)):8,v=s.useMemo(()=>n.split(`
|
|
2
|
+
`).length,[n]),z=s.useMemo(()=>Array.from({length:v},(u,l)=>l+1).join(`
|
|
3
|
+
`),[v]),[E,L]=s.useState(!1);s.useEffect(()=>{const u=()=>{const i=getComputedStyle(document.documentElement).getPropertyValue("--nc-bg").trim();L(i.startsWith("#0")||i.startsWith("#1")||i.startsWith("#2")||i.startsWith("#3"))};u();const l=new MutationObserver(u);return l.observe(document.documentElement,{attributes:!0,attributeFilter:["class","data-theme"]}),()=>l.disconnect()},[]);const w=b==="dark"||b==="auto"&&E?m.themes_exports.vsDark:m.themes_exports.vsLight,T=s.useCallback(u=>{const l=o||"text";return e.jsx(m.Highlight2,{theme:w,code:u,language:l,children:({tokens:i,getLineProps:D,getTokenProps:F})=>e.jsx(e.Fragment,{children:i.map((k,y)=>{let j=0;return e.jsxs("div",{...D({line:k}),children:[k.map((C,W)=>{const N=F({token:C}),M=A(C.content,c,h,j);return j=M.column,e.jsx("span",{...N,style:{...N.style,opacity:t?.7:void 0},children:M.content},W)}),c&&y<i.length-1&&e.jsx("span",{className:"nc-code-editor-line-ending","aria-hidden":"true",children:"↵"})]},y)})})})},[w,o,h,t,c]),g=s.useRef(null),f=s.useRef(null),_=()=>{g.current&&f.current&&(f.current.scrollTop=g.current.scrollTop)};return e.jsxs("div",{className:`nc-code-editor ${R}`.trim(),style:{display:"flex",flexDirection:"column",gap:4,...q},children:[e.jsx("style",{children:`
|
|
4
|
+
.code-editor-container,
|
|
5
|
+
.code-editor-container * {
|
|
6
|
+
white-space: pre !important;
|
|
7
|
+
overflow-wrap: normal !important;
|
|
8
|
+
word-wrap: normal !important;
|
|
9
|
+
word-break: keep-all !important;
|
|
10
|
+
}
|
|
11
|
+
.code-editor-container textarea,
|
|
12
|
+
.code-editor-container pre {
|
|
13
|
+
white-space: pre !important;
|
|
14
|
+
overflow-wrap: normal !important;
|
|
15
|
+
word-wrap: normal !important;
|
|
16
|
+
word-break: keep-all !important;
|
|
17
|
+
overflow-x: visible !important;
|
|
18
|
+
resize: none !important;
|
|
19
|
+
}
|
|
20
|
+
.code-editor-container.read-only textarea {
|
|
21
|
+
caret-color: transparent !important;
|
|
22
|
+
color: var(--nc-text-weak) !important;
|
|
23
|
+
}
|
|
24
|
+
.nc-code-editor .token.tag {
|
|
25
|
+
display: inline;
|
|
26
|
+
padding: 0;
|
|
27
|
+
border: 0;
|
|
28
|
+
border-radius: 0;
|
|
29
|
+
background: transparent;
|
|
30
|
+
color: inherit;
|
|
31
|
+
font-size: inherit;
|
|
32
|
+
font-weight: inherit;
|
|
33
|
+
white-space: inherit;
|
|
34
|
+
}
|
|
35
|
+
`}),e.jsxs("div",{className:"nc-code-editor-container",style:{border:"1px solid var(--nc-border)",background:t?"var(--nc-bg-secondary)":"var(--nc-bg-tertiary)",minHeight:r,maxHeight:x,display:"flex"},children:[d&&e.jsx("div",{ref:f,style:{padding:"10px 8px",paddingRight:12,background:"var(--nc-bg-tertiary)",borderRight:"1px solid var(--nc-border)",color:"var(--nc-text-weak)",fontFamily:'Consolas, Monaco, "Courier New", monospace',fontSize:13,lineHeight:"1.5",textAlign:"right",userSelect:"none",whiteSpace:"pre",minWidth:40,overflow:"hidden"},children:z}),e.jsx("div",{ref:g,className:`code-editor-container${t?" read-only":""}`,style:{flex:1,overflowX:"auto",overflowY:"auto",color:"var(--nc-text)"},onScroll:_,children:e.jsx(m._default,{value:n,onValueChange:a,highlight:T,padding:10,readOnly:t,style:{fontFamily:'Consolas, Monaco, "Courier New", monospace',fontSize:13,lineHeight:"1.5",minHeight:Math.max(r-2,0),background:"transparent",color:"var(--nc-text)",whiteSpace:"pre",minWidth:"max-content",tabSize:h},textareaClassName:"code-editor-textarea"})})]})]})}exports.CodeEditor=S;exports.default=S;exports.detectLanguage=H;
|
|
36
|
+
//# sourceMappingURL=code-editor.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-editor.cjs","sources":["../src/components/CodeEditor.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useMemo, useState } from 'react';\nimport Editor from 'react-simple-code-editor';\nimport { Highlight, themes } from 'prism-react-renderer';\n\nexport interface CodeEditorProps {\n value: string;\n onChange: (value: string) => void;\n /** Prism language name (e.g. 'javascript', 'python', 'yaml'). Omit for plain text. */\n language?: string;\n readOnly?: boolean;\n minHeight?: number;\n maxHeight?: number;\n /** Show line numbers gutter. Default: true. */\n lineNumbers?: boolean;\n /** Show markers for spaces, tabs, and line endings. Default: false. */\n showWhitespace?: boolean;\n /** Number of columns occupied by a tab. Default: 8. */\n tabSize?: number;\n /** Prism color theme. Defaults to automatic document theme detection. */\n colorTheme?: 'light' | 'dark' | 'auto';\n className?: string;\n style?: React.CSSProperties;\n}\n\ninterface RenderedToken {\n content: React.ReactNode;\n column: number;\n}\n\nfunction renderTokenContent(content: string, showWhitespace: boolean, tabSize: number, startColumn: number): RenderedToken {\n if (!showWhitespace) {\n return { content, column: startColumn + content.length };\n }\n\n let column = startColumn;\n const rendered = Array.from(content, (character, index) => {\n if (character === ' ') {\n column++;\n return <span key={index} className=\"nc-code-editor-whitespace\" aria-hidden=\"true\">·</span>;\n }\n if (character === '\\t') {\n const width = tabSize - (column % tabSize);\n column += width;\n return (\n <span\n key={index}\n className=\"nc-code-editor-whitespace nc-code-editor-tab\"\n style={{ width: `${width}ch` }}\n aria-hidden=\"true\"\n >\n →\n </span>\n );\n }\n column++;\n return character;\n });\n\n return { content: rendered, column };\n}\n\n/**\n * Map a filename (or file extension) to a Prism language name.\n * Returns undefined if the language is not recognized.\n */\nexport function detectLanguage(filename: string): string | undefined {\n const ext = filename.split('.').pop()?.toLowerCase();\n if (!ext) return undefined;\n\n const extMap: Record<string, string> = {\n ts: 'typescript',\n tsx: 'tsx',\n js: 'javascript',\n jsx: 'jsx',\n json: 'json',\n yaml: 'yaml',\n yml: 'yaml',\n py: 'python',\n rb: 'ruby',\n rs: 'rust',\n go: 'go',\n java: 'java',\n c: 'c',\n cpp: 'cpp',\n h: 'c',\n hpp: 'cpp',\n cs: 'csharp',\n sh: 'bash',\n bash: 'bash',\n zsh: 'bash',\n fish: 'bash',\n md: 'markdown',\n markdown: 'markdown',\n html: 'html',\n htm: 'html',\n css: 'css',\n scss: 'scss',\n sql: 'sql',\n xml: 'xml',\n svg: 'xml',\n toml: 'toml',\n ini: 'ini',\n cfg: 'ini',\n conf: 'ini',\n properties: 'properties',\n env: 'properties',\n nginx: 'nginx',\n dockerfile: 'docker',\n makefile: 'makefile',\n cmake: 'cmake',\n lua: 'lua',\n php: 'php',\n pl: 'perl',\n pm: 'perl',\n r: 'r',\n swift: 'swift',\n kt: 'kotlin',\n scala: 'scala',\n dart: 'dart',\n graphql: 'graphql',\n proto: 'protobuf',\n };\n\n // Check by extension first, then by full filename for special files\n if (extMap[ext]) return extMap[ext];\n\n const baseName = filename.toLowerCase();\n if (extMap[baseName]) return extMap[baseName];\n\n return undefined;\n}\n\nfunction CodeEditor({\n value,\n onChange,\n language,\n readOnly = false,\n minHeight = 100,\n maxHeight,\n lineNumbers: showLineNumbers = true,\n showWhitespace = false,\n tabSize = 8,\n colorTheme = 'auto',\n className = '',\n style = {},\n}: CodeEditorProps) {\n const normalizedTabSize = Number.isFinite(tabSize) ? Math.max(1, Math.floor(tabSize)) : 8;\n\n // Count lines for line numbers\n const lineCount = useMemo(() => {\n return value.split('\\n').length;\n }, [value]);\n\n // Generate line numbers\n const lineNumbers = useMemo(() => {\n return Array.from({ length: lineCount }, (_, i) => i + 1).join('\\n');\n }, [lineCount]);\n\n // Determine if we're in dark mode\n const [isDark, setIsDark] = useState(false);\n useEffect(() => {\n const checkDark = () => {\n const bg = getComputedStyle(document.documentElement).getPropertyValue('--nc-bg').trim();\n setIsDark(bg.startsWith('#0') || bg.startsWith('#1') || bg.startsWith('#2') || bg.startsWith('#3'));\n };\n checkDark();\n const observer = new MutationObserver(checkDark);\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class', 'data-theme'] });\n return () => observer.disconnect();\n }, []);\n\n const theme = (colorTheme === 'dark' || (colorTheme === 'auto' && isDark)) ? themes.vsDark : themes.vsLight;\n\n // Highlight function\n const highlightWithTheme = useCallback(\n (code: string) => {\n const highlightLanguage = language || 'text';\n return (\n <Highlight theme={theme} code={code} language={highlightLanguage}>\n {({ tokens, getLineProps, getTokenProps }) => (\n <>\n {tokens.map((line, i) => {\n let column = 0;\n return (\n <div key={i} {...getLineProps({ line })}>\n {line.map((token, key) => {\n const props = getTokenProps({ token });\n const renderedToken = renderTokenContent(\n token.content,\n showWhitespace,\n normalizedTabSize,\n column,\n );\n column = renderedToken.column;\n return (\n <span\n key={key}\n {...props}\n style={{\n ...props.style,\n opacity: readOnly ? 0.7 : undefined,\n }}\n >\n {renderedToken.content}\n </span>\n );\n })}\n {showWhitespace && i < tokens.length - 1 && (\n <span className=\"nc-code-editor-line-ending\" aria-hidden=\"true\">↵</span>\n )}\n </div>\n );\n })}\n </>\n )}\n </Highlight>\n );\n },\n [theme, language, normalizedTabSize, readOnly, showWhitespace]\n );\n\n const editorContainerRef = useRef<HTMLDivElement>(null);\n const lineNumbersRef = useRef<HTMLDivElement>(null);\n\n const handleEditorScroll = () => {\n if (editorContainerRef.current && lineNumbersRef.current) {\n lineNumbersRef.current.scrollTop = editorContainerRef.current.scrollTop;\n }\n };\n\n return (\n <div\n className={`nc-code-editor ${className}`.trim()}\n style={{ display: 'flex', flexDirection: 'column', gap: 4, ...style }}\n >\n <style>{`\n .code-editor-container,\n .code-editor-container * {\n white-space: pre !important;\n overflow-wrap: normal !important;\n word-wrap: normal !important;\n word-break: keep-all !important;\n }\n .code-editor-container textarea,\n .code-editor-container pre {\n white-space: pre !important;\n overflow-wrap: normal !important;\n word-wrap: normal !important;\n word-break: keep-all !important;\n overflow-x: visible !important;\n resize: none !important;\n }\n .code-editor-container.read-only textarea {\n caret-color: transparent !important;\n color: var(--nc-text-weak) !important;\n }\n .nc-code-editor .token.tag {\n display: inline;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: inherit;\n font-size: inherit;\n font-weight: inherit;\n white-space: inherit;\n }\n `}</style>\n <div\n className=\"nc-code-editor-container\"\n style={{\n border: '1px solid var(--nc-border)',\n background: readOnly ? 'var(--nc-bg-secondary)' : 'var(--nc-bg-tertiary)',\n minHeight,\n maxHeight,\n display: 'flex',\n }}\n >\n {/* Line numbers gutter */}\n {showLineNumbers && (\n <div\n ref={lineNumbersRef}\n style={{\n padding: '10px 8px',\n paddingRight: 12,\n background: 'var(--nc-bg-tertiary)',\n borderRight: '1px solid var(--nc-border)',\n color: 'var(--nc-text-weak)',\n fontFamily: 'Consolas, Monaco, \"Courier New\", monospace',\n fontSize: 13,\n lineHeight: '1.5',\n textAlign: 'right',\n userSelect: 'none',\n whiteSpace: 'pre',\n minWidth: 40,\n overflow: 'hidden',\n }}\n >\n {lineNumbers}\n </div>\n )}\n\n {/* Editor */}\n <div\n ref={editorContainerRef}\n className={`code-editor-container${readOnly ? ' read-only' : ''}`}\n style={{\n flex: 1,\n overflowX: 'auto',\n overflowY: 'auto',\n color: 'var(--nc-text)',\n }}\n onScroll={handleEditorScroll}\n >\n <Editor\n value={value}\n onValueChange={onChange}\n highlight={highlightWithTheme}\n padding={10}\n readOnly={readOnly}\n style={{\n fontFamily: 'Consolas, Monaco, \"Courier New\", monospace',\n fontSize: 13,\n lineHeight: '1.5',\n minHeight: Math.max(minHeight - 2, 0),\n background: 'transparent',\n color: 'var(--nc-text)',\n whiteSpace: 'pre',\n minWidth: 'max-content',\n tabSize: normalizedTabSize,\n }}\n textareaClassName=\"code-editor-textarea\"\n />\n </div>\n </div>\n </div>\n );\n}\n\nexport { CodeEditor };\nexport default CodeEditor;\n"],"names":["renderTokenContent","content","showWhitespace","tabSize","startColumn","column","character","index","width","jsx","detectLanguage","filename","ext","_a","extMap","baseName","CodeEditor","value","onChange","language","readOnly","minHeight","maxHeight","showLineNumbers","colorTheme","className","style","normalizedTabSize","lineCount","useMemo","lineNumbers","_","i","isDark","setIsDark","useState","useEffect","checkDark","bg","observer","theme","themes","highlightWithTheme","useCallback","code","highlightLanguage","Highlight","tokens","getLineProps","getTokenProps","Fragment","line","token","key","props","renderedToken","editorContainerRef","useRef","lineNumbersRef","handleEditorScroll","jsxs","Editor"],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { default as default_2 } from 'react';
|
|
2
|
+
import { JSX as JSX_2 } from 'react/jsx-runtime';
|
|
3
|
+
|
|
4
|
+
declare function CodeEditor({ value, onChange, language, readOnly, minHeight, maxHeight, lineNumbers: showLineNumbers, showWhitespace, tabSize, colorTheme, className, style, }: CodeEditorProps): JSX_2.Element;
|
|
5
|
+
export { CodeEditor }
|
|
6
|
+
export default CodeEditor;
|
|
7
|
+
|
|
8
|
+
export declare interface CodeEditorProps {
|
|
9
|
+
value: string;
|
|
10
|
+
onChange: (value: string) => void;
|
|
11
|
+
/** Prism language name (e.g. 'javascript', 'python', 'yaml'). Omit for plain text. */
|
|
12
|
+
language?: string;
|
|
13
|
+
readOnly?: boolean;
|
|
14
|
+
minHeight?: number;
|
|
15
|
+
maxHeight?: number;
|
|
16
|
+
/** Show line numbers gutter. Default: true. */
|
|
17
|
+
lineNumbers?: boolean;
|
|
18
|
+
/** Show markers for spaces, tabs, and line endings. Default: false. */
|
|
19
|
+
showWhitespace?: boolean;
|
|
20
|
+
/** Number of columns occupied by a tab. Default: 8. */
|
|
21
|
+
tabSize?: number;
|
|
22
|
+
/** Prism color theme. Defaults to automatic document theme detection. */
|
|
23
|
+
colorTheme?: 'light' | 'dark' | 'auto';
|
|
24
|
+
className?: string;
|
|
25
|
+
style?: default_2.CSSProperties;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Map a filename (or file extension) to a Prism language name.
|
|
30
|
+
* Returns undefined if the language is not recognized.
|
|
31
|
+
*/
|
|
32
|
+
export declare function detectLanguage(filename: string): string | undefined;
|
|
33
|
+
|
|
34
|
+
export { }
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { jsx as o, Fragment as A, jsxs as g } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo as S, useState as $, useEffect as V, useCallback as I, useRef as M } from "react";
|
|
3
|
+
import { t as z, H as P, _ as X } from "./index-BZJJwrMY.js";
|
|
4
|
+
function Y(r, a, n, e) {
|
|
5
|
+
if (!a)
|
|
6
|
+
return { content: r, column: e + r.length };
|
|
7
|
+
let t = e;
|
|
8
|
+
return { content: Array.from(r, (c, s) => {
|
|
9
|
+
if (c === " ")
|
|
10
|
+
return t++, /* @__PURE__ */ o("span", { className: "nc-code-editor-whitespace", "aria-hidden": "true", children: "·" }, s);
|
|
11
|
+
if (c === " ") {
|
|
12
|
+
const l = n - t % n;
|
|
13
|
+
return t += l, /* @__PURE__ */ o(
|
|
14
|
+
"span",
|
|
15
|
+
{
|
|
16
|
+
className: "nc-code-editor-whitespace nc-code-editor-tab",
|
|
17
|
+
style: { width: `${l}ch` },
|
|
18
|
+
"aria-hidden": "true",
|
|
19
|
+
children: "→"
|
|
20
|
+
},
|
|
21
|
+
s
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
return t++, c;
|
|
25
|
+
}), column: t };
|
|
26
|
+
}
|
|
27
|
+
function K(r) {
|
|
28
|
+
var t;
|
|
29
|
+
const a = (t = r.split(".").pop()) == null ? void 0 : t.toLowerCase();
|
|
30
|
+
if (!a) return;
|
|
31
|
+
const n = {
|
|
32
|
+
ts: "typescript",
|
|
33
|
+
tsx: "tsx",
|
|
34
|
+
js: "javascript",
|
|
35
|
+
jsx: "jsx",
|
|
36
|
+
json: "json",
|
|
37
|
+
yaml: "yaml",
|
|
38
|
+
yml: "yaml",
|
|
39
|
+
py: "python",
|
|
40
|
+
rb: "ruby",
|
|
41
|
+
rs: "rust",
|
|
42
|
+
go: "go",
|
|
43
|
+
java: "java",
|
|
44
|
+
c: "c",
|
|
45
|
+
cpp: "cpp",
|
|
46
|
+
h: "c",
|
|
47
|
+
hpp: "cpp",
|
|
48
|
+
cs: "csharp",
|
|
49
|
+
sh: "bash",
|
|
50
|
+
bash: "bash",
|
|
51
|
+
zsh: "bash",
|
|
52
|
+
fish: "bash",
|
|
53
|
+
md: "markdown",
|
|
54
|
+
markdown: "markdown",
|
|
55
|
+
html: "html",
|
|
56
|
+
htm: "html",
|
|
57
|
+
css: "css",
|
|
58
|
+
scss: "scss",
|
|
59
|
+
sql: "sql",
|
|
60
|
+
xml: "xml",
|
|
61
|
+
svg: "xml",
|
|
62
|
+
toml: "toml",
|
|
63
|
+
ini: "ini",
|
|
64
|
+
cfg: "ini",
|
|
65
|
+
conf: "ini",
|
|
66
|
+
properties: "properties",
|
|
67
|
+
env: "properties",
|
|
68
|
+
nginx: "nginx",
|
|
69
|
+
dockerfile: "docker",
|
|
70
|
+
makefile: "makefile",
|
|
71
|
+
cmake: "cmake",
|
|
72
|
+
lua: "lua",
|
|
73
|
+
php: "php",
|
|
74
|
+
pl: "perl",
|
|
75
|
+
pm: "perl",
|
|
76
|
+
r: "r",
|
|
77
|
+
swift: "swift",
|
|
78
|
+
kt: "kotlin",
|
|
79
|
+
scala: "scala",
|
|
80
|
+
dart: "dart",
|
|
81
|
+
graphql: "graphql",
|
|
82
|
+
proto: "protobuf"
|
|
83
|
+
};
|
|
84
|
+
if (n[a]) return n[a];
|
|
85
|
+
const e = r.toLowerCase();
|
|
86
|
+
if (n[e]) return n[e];
|
|
87
|
+
}
|
|
88
|
+
function Q({
|
|
89
|
+
value: r,
|
|
90
|
+
onChange: a,
|
|
91
|
+
language: n,
|
|
92
|
+
readOnly: e = !1,
|
|
93
|
+
minHeight: t = 100,
|
|
94
|
+
maxHeight: f,
|
|
95
|
+
lineNumbers: c = !0,
|
|
96
|
+
showWhitespace: s = !1,
|
|
97
|
+
tabSize: l = 8,
|
|
98
|
+
colorTheme: b = "auto",
|
|
99
|
+
className: L = "",
|
|
100
|
+
style: D = {}
|
|
101
|
+
}) {
|
|
102
|
+
const m = Number.isFinite(l) ? Math.max(1, Math.floor(l)) : 8, x = S(() => r.split(`
|
|
103
|
+
`).length, [r]), E = S(() => Array.from({ length: x }, (d, p) => p + 1).join(`
|
|
104
|
+
`), [x]), [F, R] = $(!1);
|
|
105
|
+
V(() => {
|
|
106
|
+
const d = () => {
|
|
107
|
+
const i = getComputedStyle(document.documentElement).getPropertyValue("--nc-bg").trim();
|
|
108
|
+
R(i.startsWith("#0") || i.startsWith("#1") || i.startsWith("#2") || i.startsWith("#3"));
|
|
109
|
+
};
|
|
110
|
+
d();
|
|
111
|
+
const p = new MutationObserver(d);
|
|
112
|
+
return p.observe(document.documentElement, { attributes: !0, attributeFilter: ["class", "data-theme"] }), () => p.disconnect();
|
|
113
|
+
}, []);
|
|
114
|
+
const w = b === "dark" || b === "auto" && F ? z.vsDark : z.vsLight, T = I(
|
|
115
|
+
(d) => /* @__PURE__ */ o(P, { theme: w, code: d, language: n || "text", children: ({ tokens: i, getLineProps: q, getTokenProps: H }) => /* @__PURE__ */ o(A, { children: i.map((v, k) => {
|
|
116
|
+
let y = 0;
|
|
117
|
+
return /* @__PURE__ */ g("div", { ...q({ line: v }), children: [
|
|
118
|
+
v.map((N, _) => {
|
|
119
|
+
const C = H({ token: N }), j = Y(
|
|
120
|
+
N.content,
|
|
121
|
+
s,
|
|
122
|
+
m,
|
|
123
|
+
y
|
|
124
|
+
);
|
|
125
|
+
return y = j.column, /* @__PURE__ */ o(
|
|
126
|
+
"span",
|
|
127
|
+
{
|
|
128
|
+
...C,
|
|
129
|
+
style: {
|
|
130
|
+
...C.style,
|
|
131
|
+
opacity: e ? 0.7 : void 0
|
|
132
|
+
},
|
|
133
|
+
children: j.content
|
|
134
|
+
},
|
|
135
|
+
_
|
|
136
|
+
);
|
|
137
|
+
}),
|
|
138
|
+
s && k < i.length - 1 && /* @__PURE__ */ o("span", { className: "nc-code-editor-line-ending", "aria-hidden": "true", children: "↵" })
|
|
139
|
+
] }, k);
|
|
140
|
+
}) }) }),
|
|
141
|
+
[w, n, m, e, s]
|
|
142
|
+
), h = M(null), u = M(null), W = () => {
|
|
143
|
+
h.current && u.current && (u.current.scrollTop = h.current.scrollTop);
|
|
144
|
+
};
|
|
145
|
+
return /* @__PURE__ */ g(
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
className: `nc-code-editor ${L}`.trim(),
|
|
149
|
+
style: { display: "flex", flexDirection: "column", gap: 4, ...D },
|
|
150
|
+
children: [
|
|
151
|
+
/* @__PURE__ */ o("style", { children: `
|
|
152
|
+
.code-editor-container,
|
|
153
|
+
.code-editor-container * {
|
|
154
|
+
white-space: pre !important;
|
|
155
|
+
overflow-wrap: normal !important;
|
|
156
|
+
word-wrap: normal !important;
|
|
157
|
+
word-break: keep-all !important;
|
|
158
|
+
}
|
|
159
|
+
.code-editor-container textarea,
|
|
160
|
+
.code-editor-container pre {
|
|
161
|
+
white-space: pre !important;
|
|
162
|
+
overflow-wrap: normal !important;
|
|
163
|
+
word-wrap: normal !important;
|
|
164
|
+
word-break: keep-all !important;
|
|
165
|
+
overflow-x: visible !important;
|
|
166
|
+
resize: none !important;
|
|
167
|
+
}
|
|
168
|
+
.code-editor-container.read-only textarea {
|
|
169
|
+
caret-color: transparent !important;
|
|
170
|
+
color: var(--nc-text-weak) !important;
|
|
171
|
+
}
|
|
172
|
+
.nc-code-editor .token.tag {
|
|
173
|
+
display: inline;
|
|
174
|
+
padding: 0;
|
|
175
|
+
border: 0;
|
|
176
|
+
border-radius: 0;
|
|
177
|
+
background: transparent;
|
|
178
|
+
color: inherit;
|
|
179
|
+
font-size: inherit;
|
|
180
|
+
font-weight: inherit;
|
|
181
|
+
white-space: inherit;
|
|
182
|
+
}
|
|
183
|
+
` }),
|
|
184
|
+
/* @__PURE__ */ g(
|
|
185
|
+
"div",
|
|
186
|
+
{
|
|
187
|
+
className: "nc-code-editor-container",
|
|
188
|
+
style: {
|
|
189
|
+
border: "1px solid var(--nc-border)",
|
|
190
|
+
background: e ? "var(--nc-bg-secondary)" : "var(--nc-bg-tertiary)",
|
|
191
|
+
minHeight: t,
|
|
192
|
+
maxHeight: f,
|
|
193
|
+
display: "flex"
|
|
194
|
+
},
|
|
195
|
+
children: [
|
|
196
|
+
c && /* @__PURE__ */ o(
|
|
197
|
+
"div",
|
|
198
|
+
{
|
|
199
|
+
ref: u,
|
|
200
|
+
style: {
|
|
201
|
+
padding: "10px 8px",
|
|
202
|
+
paddingRight: 12,
|
|
203
|
+
background: "var(--nc-bg-tertiary)",
|
|
204
|
+
borderRight: "1px solid var(--nc-border)",
|
|
205
|
+
color: "var(--nc-text-weak)",
|
|
206
|
+
fontFamily: 'Consolas, Monaco, "Courier New", monospace',
|
|
207
|
+
fontSize: 13,
|
|
208
|
+
lineHeight: "1.5",
|
|
209
|
+
textAlign: "right",
|
|
210
|
+
userSelect: "none",
|
|
211
|
+
whiteSpace: "pre",
|
|
212
|
+
minWidth: 40,
|
|
213
|
+
overflow: "hidden"
|
|
214
|
+
},
|
|
215
|
+
children: E
|
|
216
|
+
}
|
|
217
|
+
),
|
|
218
|
+
/* @__PURE__ */ o(
|
|
219
|
+
"div",
|
|
220
|
+
{
|
|
221
|
+
ref: h,
|
|
222
|
+
className: `code-editor-container${e ? " read-only" : ""}`,
|
|
223
|
+
style: {
|
|
224
|
+
flex: 1,
|
|
225
|
+
overflowX: "auto",
|
|
226
|
+
overflowY: "auto",
|
|
227
|
+
color: "var(--nc-text)"
|
|
228
|
+
},
|
|
229
|
+
onScroll: W,
|
|
230
|
+
children: /* @__PURE__ */ o(
|
|
231
|
+
X,
|
|
232
|
+
{
|
|
233
|
+
value: r,
|
|
234
|
+
onValueChange: a,
|
|
235
|
+
highlight: T,
|
|
236
|
+
padding: 10,
|
|
237
|
+
readOnly: e,
|
|
238
|
+
style: {
|
|
239
|
+
fontFamily: 'Consolas, Monaco, "Courier New", monospace',
|
|
240
|
+
fontSize: 13,
|
|
241
|
+
lineHeight: "1.5",
|
|
242
|
+
minHeight: Math.max(t - 2, 0),
|
|
243
|
+
background: "transparent",
|
|
244
|
+
color: "var(--nc-text)",
|
|
245
|
+
whiteSpace: "pre",
|
|
246
|
+
minWidth: "max-content",
|
|
247
|
+
tabSize: m
|
|
248
|
+
},
|
|
249
|
+
textareaClassName: "code-editor-textarea"
|
|
250
|
+
}
|
|
251
|
+
)
|
|
252
|
+
}
|
|
253
|
+
)
|
|
254
|
+
]
|
|
255
|
+
}
|
|
256
|
+
)
|
|
257
|
+
]
|
|
258
|
+
}
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
export {
|
|
262
|
+
Q as CodeEditor,
|
|
263
|
+
Q as default,
|
|
264
|
+
K as detectLanguage
|
|
265
|
+
};
|
|
266
|
+
//# sourceMappingURL=code-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-editor.js","sources":["../src/components/CodeEditor.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useRef, useMemo, useState } from 'react';\nimport Editor from 'react-simple-code-editor';\nimport { Highlight, themes } from 'prism-react-renderer';\n\nexport interface CodeEditorProps {\n value: string;\n onChange: (value: string) => void;\n /** Prism language name (e.g. 'javascript', 'python', 'yaml'). Omit for plain text. */\n language?: string;\n readOnly?: boolean;\n minHeight?: number;\n maxHeight?: number;\n /** Show line numbers gutter. Default: true. */\n lineNumbers?: boolean;\n /** Show markers for spaces, tabs, and line endings. Default: false. */\n showWhitespace?: boolean;\n /** Number of columns occupied by a tab. Default: 8. */\n tabSize?: number;\n /** Prism color theme. Defaults to automatic document theme detection. */\n colorTheme?: 'light' | 'dark' | 'auto';\n className?: string;\n style?: React.CSSProperties;\n}\n\ninterface RenderedToken {\n content: React.ReactNode;\n column: number;\n}\n\nfunction renderTokenContent(content: string, showWhitespace: boolean, tabSize: number, startColumn: number): RenderedToken {\n if (!showWhitespace) {\n return { content, column: startColumn + content.length };\n }\n\n let column = startColumn;\n const rendered = Array.from(content, (character, index) => {\n if (character === ' ') {\n column++;\n return <span key={index} className=\"nc-code-editor-whitespace\" aria-hidden=\"true\">·</span>;\n }\n if (character === '\\t') {\n const width = tabSize - (column % tabSize);\n column += width;\n return (\n <span\n key={index}\n className=\"nc-code-editor-whitespace nc-code-editor-tab\"\n style={{ width: `${width}ch` }}\n aria-hidden=\"true\"\n >\n →\n </span>\n );\n }\n column++;\n return character;\n });\n\n return { content: rendered, column };\n}\n\n/**\n * Map a filename (or file extension) to a Prism language name.\n * Returns undefined if the language is not recognized.\n */\nexport function detectLanguage(filename: string): string | undefined {\n const ext = filename.split('.').pop()?.toLowerCase();\n if (!ext) return undefined;\n\n const extMap: Record<string, string> = {\n ts: 'typescript',\n tsx: 'tsx',\n js: 'javascript',\n jsx: 'jsx',\n json: 'json',\n yaml: 'yaml',\n yml: 'yaml',\n py: 'python',\n rb: 'ruby',\n rs: 'rust',\n go: 'go',\n java: 'java',\n c: 'c',\n cpp: 'cpp',\n h: 'c',\n hpp: 'cpp',\n cs: 'csharp',\n sh: 'bash',\n bash: 'bash',\n zsh: 'bash',\n fish: 'bash',\n md: 'markdown',\n markdown: 'markdown',\n html: 'html',\n htm: 'html',\n css: 'css',\n scss: 'scss',\n sql: 'sql',\n xml: 'xml',\n svg: 'xml',\n toml: 'toml',\n ini: 'ini',\n cfg: 'ini',\n conf: 'ini',\n properties: 'properties',\n env: 'properties',\n nginx: 'nginx',\n dockerfile: 'docker',\n makefile: 'makefile',\n cmake: 'cmake',\n lua: 'lua',\n php: 'php',\n pl: 'perl',\n pm: 'perl',\n r: 'r',\n swift: 'swift',\n kt: 'kotlin',\n scala: 'scala',\n dart: 'dart',\n graphql: 'graphql',\n proto: 'protobuf',\n };\n\n // Check by extension first, then by full filename for special files\n if (extMap[ext]) return extMap[ext];\n\n const baseName = filename.toLowerCase();\n if (extMap[baseName]) return extMap[baseName];\n\n return undefined;\n}\n\nfunction CodeEditor({\n value,\n onChange,\n language,\n readOnly = false,\n minHeight = 100,\n maxHeight,\n lineNumbers: showLineNumbers = true,\n showWhitespace = false,\n tabSize = 8,\n colorTheme = 'auto',\n className = '',\n style = {},\n}: CodeEditorProps) {\n const normalizedTabSize = Number.isFinite(tabSize) ? Math.max(1, Math.floor(tabSize)) : 8;\n\n // Count lines for line numbers\n const lineCount = useMemo(() => {\n return value.split('\\n').length;\n }, [value]);\n\n // Generate line numbers\n const lineNumbers = useMemo(() => {\n return Array.from({ length: lineCount }, (_, i) => i + 1).join('\\n');\n }, [lineCount]);\n\n // Determine if we're in dark mode\n const [isDark, setIsDark] = useState(false);\n useEffect(() => {\n const checkDark = () => {\n const bg = getComputedStyle(document.documentElement).getPropertyValue('--nc-bg').trim();\n setIsDark(bg.startsWith('#0') || bg.startsWith('#1') || bg.startsWith('#2') || bg.startsWith('#3'));\n };\n checkDark();\n const observer = new MutationObserver(checkDark);\n observer.observe(document.documentElement, { attributes: true, attributeFilter: ['class', 'data-theme'] });\n return () => observer.disconnect();\n }, []);\n\n const theme = (colorTheme === 'dark' || (colorTheme === 'auto' && isDark)) ? themes.vsDark : themes.vsLight;\n\n // Highlight function\n const highlightWithTheme = useCallback(\n (code: string) => {\n const highlightLanguage = language || 'text';\n return (\n <Highlight theme={theme} code={code} language={highlightLanguage}>\n {({ tokens, getLineProps, getTokenProps }) => (\n <>\n {tokens.map((line, i) => {\n let column = 0;\n return (\n <div key={i} {...getLineProps({ line })}>\n {line.map((token, key) => {\n const props = getTokenProps({ token });\n const renderedToken = renderTokenContent(\n token.content,\n showWhitespace,\n normalizedTabSize,\n column,\n );\n column = renderedToken.column;\n return (\n <span\n key={key}\n {...props}\n style={{\n ...props.style,\n opacity: readOnly ? 0.7 : undefined,\n }}\n >\n {renderedToken.content}\n </span>\n );\n })}\n {showWhitespace && i < tokens.length - 1 && (\n <span className=\"nc-code-editor-line-ending\" aria-hidden=\"true\">↵</span>\n )}\n </div>\n );\n })}\n </>\n )}\n </Highlight>\n );\n },\n [theme, language, normalizedTabSize, readOnly, showWhitespace]\n );\n\n const editorContainerRef = useRef<HTMLDivElement>(null);\n const lineNumbersRef = useRef<HTMLDivElement>(null);\n\n const handleEditorScroll = () => {\n if (editorContainerRef.current && lineNumbersRef.current) {\n lineNumbersRef.current.scrollTop = editorContainerRef.current.scrollTop;\n }\n };\n\n return (\n <div\n className={`nc-code-editor ${className}`.trim()}\n style={{ display: 'flex', flexDirection: 'column', gap: 4, ...style }}\n >\n <style>{`\n .code-editor-container,\n .code-editor-container * {\n white-space: pre !important;\n overflow-wrap: normal !important;\n word-wrap: normal !important;\n word-break: keep-all !important;\n }\n .code-editor-container textarea,\n .code-editor-container pre {\n white-space: pre !important;\n overflow-wrap: normal !important;\n word-wrap: normal !important;\n word-break: keep-all !important;\n overflow-x: visible !important;\n resize: none !important;\n }\n .code-editor-container.read-only textarea {\n caret-color: transparent !important;\n color: var(--nc-text-weak) !important;\n }\n .nc-code-editor .token.tag {\n display: inline;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: inherit;\n font-size: inherit;\n font-weight: inherit;\n white-space: inherit;\n }\n `}</style>\n <div\n className=\"nc-code-editor-container\"\n style={{\n border: '1px solid var(--nc-border)',\n background: readOnly ? 'var(--nc-bg-secondary)' : 'var(--nc-bg-tertiary)',\n minHeight,\n maxHeight,\n display: 'flex',\n }}\n >\n {/* Line numbers gutter */}\n {showLineNumbers && (\n <div\n ref={lineNumbersRef}\n style={{\n padding: '10px 8px',\n paddingRight: 12,\n background: 'var(--nc-bg-tertiary)',\n borderRight: '1px solid var(--nc-border)',\n color: 'var(--nc-text-weak)',\n fontFamily: 'Consolas, Monaco, \"Courier New\", monospace',\n fontSize: 13,\n lineHeight: '1.5',\n textAlign: 'right',\n userSelect: 'none',\n whiteSpace: 'pre',\n minWidth: 40,\n overflow: 'hidden',\n }}\n >\n {lineNumbers}\n </div>\n )}\n\n {/* Editor */}\n <div\n ref={editorContainerRef}\n className={`code-editor-container${readOnly ? ' read-only' : ''}`}\n style={{\n flex: 1,\n overflowX: 'auto',\n overflowY: 'auto',\n color: 'var(--nc-text)',\n }}\n onScroll={handleEditorScroll}\n >\n <Editor\n value={value}\n onValueChange={onChange}\n highlight={highlightWithTheme}\n padding={10}\n readOnly={readOnly}\n style={{\n fontFamily: 'Consolas, Monaco, \"Courier New\", monospace',\n fontSize: 13,\n lineHeight: '1.5',\n minHeight: Math.max(minHeight - 2, 0),\n background: 'transparent',\n color: 'var(--nc-text)',\n whiteSpace: 'pre',\n minWidth: 'max-content',\n tabSize: normalizedTabSize,\n }}\n textareaClassName=\"code-editor-textarea\"\n />\n </div>\n </div>\n </div>\n );\n}\n\nexport { CodeEditor };\nexport default CodeEditor;\n"],"names":["renderTokenContent","content","showWhitespace","tabSize","startColumn","column","character","index","width","jsx","detectLanguage","filename","ext","_a","extMap","baseName","CodeEditor","value","onChange","language","readOnly","minHeight","maxHeight","showLineNumbers","colorTheme","className","style","normalizedTabSize","lineCount","useMemo","lineNumbers","_","i","isDark","setIsDark","useState","useEffect","checkDark","bg","observer","theme","themes","highlightWithTheme","useCallback","code","Highlight","tokens","getLineProps","getTokenProps","Fragment","line","token","key","props","renderedToken","editorContainerRef","useRef","lineNumbersRef","handleEditorScroll","jsxs","Editor"],"mappings":"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"}
|