8000 chore: new MultiCodeEditor component by Kikobeats · Pull Request #1783 · microlinkhq/www · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

chore: new MultiCodeEditor component #1783

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
],
"dependencies": {
"@kikobeats/use-query-state": "1.2.2",
"@microlink/mql": "~0.13.14",
"@microlink/mql": "~0.14.0",
"@microlink/react": "5.5.23",
"@microlink/recipes": "~1.8.1",
"@react-spring/web": "~9.7.5",
Expand Down Expand Up @@ -152,14 +152,14 @@
"react-confetti": "~6.4.0",
"react-dom": "18",
"react-feather": "~2.0.10",
"react-syntax-highlighter": "~15.6.1",
"react-timeago": "~7.2.0",
"react-twitter-widgets": "~1.11.0",
"rehype-slug": "~6.0.0",
"sass": "~1.86.1",
"styled-components": "~6.1.16",
"styled-is": "~1.3.0",
"styled-system": "~5.1.5",
"sugar-high": "~0.9.3",
"swr": "~2.3.3",
"tldts": "~6.1.85",
"top-crawler-agents": "~1.0.31",
Expand All @@ -183,6 +183,7 @@
"finepack": "latest",
"git-authors-cli": "latest",
"github-generate-release": "latest",
"httpsnippet": "latest",
"nano-staged": "latest",
"pretty-bytes": "latest",
"puppeteer": "latest",
Expand Down
107 changes: 63 additions & 44 deletions src/components/elements/CodeEditor/CodeEditor.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
import { cx, radii, theme, fontSizes, lineHeights, fonts } from 'theme'
import { hideScrollbar, wordBreak } from 'helpers/style'
import { getLines } from 'helpers/get-lines'
import { prettier } from 'helpers/prettier'
import { template } from 'helpers/template'
import { hash } from 'helpers/hash'

import { hideScrollbar, wordBreak } from 'helpers/style'
import React, { useState } from 'react'
import React from 'react'
import identity from 'lodash/identity'
import { highlight } from 'sugar-high'
import styled from 'styled-components'
import { cx, radii, theme } from 'theme'
import { hash } from 'helpers/hash'
import range from 'lodash/range'
import get from 'dlv'

import codeTheme from './theme'
import Runkit from '../Runkit/Runkit'
import { getLanguageTheme } from './theme'

import Terminal, { TERMINAL_WIDTH, TERMINAL_HEIGHT } from '../Terminal/Terminal'

Expand Down Expand Up @@ -47,11 +45,54 @@ const generateHighlightLines = linesRange => {
const getClassName = ({ className, metastring = '' }) =>
className ? className + metastring : ''

const CustomSyntaxHighlighter = styled(SyntaxHighlighter)`
const CustomCodeBlock = styled.pre`
${hideScrollbar};
${props => codeTheme[props.$theme]};

margin: 0;
padding: 0;
overflow: auto;
position: relative;
background: ${props => (props.$theme === 'dark' ? cx('black') : cx('white'))};
color: ${props => (props.$theme === 'dark' ? cx('white') : cx('black'))};

code {
display: block;
white-space: pre;
overflow-x: auto;
padding-left: ${props => (props.$showLineNumbers ? '3rem' : '0')};
font-family: ${fonts.mono};
font-size: ${fontSizes[0]};
line-height: ${lineHeights[2]};
tab-size: 2;
}

.line-numbers {
position: absolute;
top: 0;
left: 0;
width: 3rem;
padding: 0;
margin: 0;
color: ${props =>
props.$theme === 'dark' ? cx('white50') : cx('black50')};
background: ${props =>
props.$theme === 'dark' ? cx('black') : cx('white')};
border-right: 1px solid
${props => (props.$theme === 'dark' ? cx('white10') : cx('black10'))};
text-align: right;
padding-right: 0.5rem;
font-size: ${fontSizes[0]};
line-height: ${lineHeights[2]};
user-select: none;
pointer-events: none;
}
`

const generateLineNumbers = text => {
const lines = text.split('\n')
return lines.map((_, index) => index + 1).join('\n')
}

const TerminalTextWrapper = styled('div')`
${wordBreak};
width: 100%;
Expand All @@ -68,7 +109,6 @@ const getLanguage = ({ className, language, title }) => {

const CodeEditor = ({
children,
interactive: runkitProps = {},
showLineNumbers = false,
isDark = false,
language: languageProp,
Expand All @@ -86,30 +126,24 @@ const CodeEditor = ({
const text = pretty(template(children)).trim()
const id = `codeditor-${hash(children)}-${themeKey}`

const isInteractive =
runkitProps !== false && Runkit.isSupported({ language, text })

const [isLoaded, setIsLoaded] = useState(!isInteractive)

const highLightLinesSelector = generateHighlightLines(highlightLines)
const firstHighlightLine = highLightLinesSelector && highLightLinesSelector[0]
const lastHighlightLine =
highLightLinesSelector &&
highLightLinesSelector[highLightLinesSelector.length - 1]

const TerminalComponent = (
return (
<Terminal
title={title}
isDark={isDark}
id={id}
text={text}
loading={!isLoaded}
css={theme({ width: TERMINAL_WIDTH })}
blinkCursor={blinkCursor}
{...props}
>
<TerminalTextWrapper>
<CustomSyntaxHighlighter
<CustomCodeBlock
css={`
${String(highLightLinesSelector)} {
display: block;
Expand All @@ -123,38 +157,23 @@ const CodeEditor = ({
border-bottom-left-radius: ${radii[2]};
border-bottom-right-radius: ${radii[2]};
}

/* Apply language-specific CSS custom properties */
${getLanguageTheme(language, themeKey) || ''}
`}
useInlineStyles={false}
$theme={themeKey}
$language={language}
$highlightLines={highlightLines}
showLineNumbers={showLineNumbers}
language={language}
style={{}}
wrapLines
$showLineNumbers={showLineNumbers}
>
{text}
</CustomSyntaxHighlighter>
{showLineNumbers && (
<pre className='line-numbers'>{generateLineNumbers(text)}</pre>
)}
<code dangerouslySetInnerHTML={{ __html: highlight(text) }} />
</CustomCodeBlock>
</TerminalTextWrapper>
</Terminal>
)

if (!isInteractive) return TerminalComponent

return (
<Runkit
{...runkitProps}
isDark={isDark}
title={title}
placeholderComponent={TerminalComponent}
source={text}
=> {
setIsLoaded(true)
element.style['padding-top'] = '4px'
element.style['padding-bottom'] = 0
element.style['overflow-x'] = 'hidden'
}}
/>
)
}

CodeEditor.width = TERMINAL_WIDTH
Expand Down
94 changes: 43 additions & 51 deletions src/components/elements/CodeEditor/theme.js
< F3C5 td id="diff-d09ad1f018f957202420e5c884939d25184f2e5288c82312206e30e4af6089b0R36" data-line-number="36" class="blob-num blob-num-addition js-linkable-line-number js-blob-rnum">
Original file line number Diff line number Diff line change
@@ -1,58 +1,50 @@
import { fontSizes, lineHeights, fonts, cx } from 'theme'
import { css } from 'styled-components'
// Function to get CSS custom properties for specific language
export const getLanguageTheme = (language, themeKey) => {
const normalizedLang = language?.toLowerCase()

const base = ({ background, primary, secondary }) => css`
margin: 0;
code {
font-family: ${fonts.mono};
font-size: ${fontSizes[0]};
line-height: ${lineHeights[2]};
direction: ltr;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
tab-size 2;
hyphens: none;
background ${background};
color: ${primary};
// Map language aliases to main language keys
const languageMap = {
js: 'javascript',
jsx: 'javascript',
ts: 'javascript',
tsx: 'javascript',
'node.js': 'javascript',
shell: 'bash',
sh: 'bash',
curl: 'bash'
}
pre {
padding: 0px 1em 0px 0px;
margin: .5em 0;
overflow: auto;
};

.keyword,
.attr-name,
.arrow,
.punctuation,
.operator {
color: ${secondary};
}
.keyword,
.template-string {
color: ${primary};
}
`
const mappedLang = languageMap[normalizedLang] || normalizedLang

const theme = {
light: {
background: cx('white'),
primary: cx('black'),
secondary: cx('black50')
},
dark: {
background: cx('black'),
primary: cx('white'),
secondary: cx('white50')
}
}
console.log(mappedLang)

const codeTheme = {
theme,
dark: base(theme.dark),
light: base(theme.light)
return languageColors[mappedLang]?.[themeKey]
}

export default codeTheme
// Language-specific CSS custom properties for sugar-high tokens
const languageColors = {
json: {
light: `
--sh-class: var(--black);
--sh-identifier: var(--black);
--sh-sign: var(--black50);
--sh-property: var(--black);
--sh-entity: var(--black);
--sh-jsxliterals: var(--black);
--sh-string: var(--black);
--sh-keyword: var(--black);
--sh-comment: var(--black);
`,
dark: `
--sh-class: var(--black);
--sh-identifier: var(--black);
--sh-sign: var(--black50);
--sh-property: var(--black);
--sh-entity: var(--black);
--sh-jsxliterals: var(--black);
--sh-string: var(--black);
--sh-keyword: var(--black);
--sh-comment: var(--black);
`
}
}
25 changes: 4 additions & 21 deletions src/components/elements/MultiCodeEditor/MultiCodeEditor.stories.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,18 @@
import { MultiCodeEditor, Box, Text } from 'components/elements'
import MultiCodeEditorV2 from './MultiCodeEditorV2'
import { Box, Text } from 'components/elements'
import { storiesOf } from '@storybook/react'
import { mqlCode } from 'helpers/mql-code'
import { mqlCode } from 'helpers/mql-code-v2'
import { theme } from 'theme'
import { Story } from 'story'
import React from 'react'

const languages = mqlCode('https://example.com', {
data: {
audio: true,
video: true,
meta: true,
pdf: {
format: 'A4',
margin: '0.35cm',
scale: 0.6
}
}
})

storiesOf('Elements', module).add('MultiCodeEditor', () => (
<Story name='MultiCodeEditor'>
<Box css={theme({ mb: 4, width: 650 })}>
<Text css={theme({ color: 'gray6', mb: 2, fontSize: 0 })}>
{'<MultiCodeEditor />'}
</Text>
<MultiCodeEditor languages={languages} />
<Box css={theme({ py: 3 })} />
<Text css={theme({ color: 'gray6', mb: 2, fontSize: 0 })}>
{'<MultiCodeEditor isDark />'}
</Text>
<MultiCodeEditor languages={languages} isDark />
<MultiCodeEditorV2 mqlCode={mqlCode('https://github.com/microlinkhq')} />
</Box>
</Story>
))
Loading
Loading
0