Skip to content

Commit

Permalink
fix: overflow for source code editor (#2014)
Browse files Browse the repository at this point in the history
* fix: source code should wrap

* fix: code scroll

* chore: optimize

* chore: code opt

* chore: code clean
  • Loading branch information
MadCcc committed Jan 24, 2024
1 parent 5d169bb commit eb7f122
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 77 deletions.
25 changes: 25 additions & 0 deletions src/client/theme-default/builtins/SourceCode/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,32 @@
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;

&-scroll-container {
overflow: auto;
width: 100%;
height: 100%;
}

&-scroll-content {
position: relative;
width: max-content;
height: max-content;
min-width: 100%;
min-height: 100%;

> pre.prism-code {
width: max-content;
position: relative;
overflow: visible;
}
}

> pre.prism-code {
overflow: auto;
}

> pre.prism-code,
&-scroll-content > pre.prism-code {
margin: 0;
padding: 18px 24px;
font-size: 14px;
Expand Down
92 changes: 53 additions & 39 deletions src/client/theme-default/builtins/SourceCode/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface SourceCodeProps {
lang: Language;
highlightLines?: number[];
extra?: ReactNode;
textarea?: ReactNode;
}

const SourceCode: FC<SourceCodeProps> = (props) => {
Expand All @@ -44,6 +45,48 @@ const SourceCode: FC<SourceCodeProps> = (props) => {
}
}, [lang, children]);

const code = (
<Highlight
{...defaultProps}
code={children}
language={SIMILAR_DSL[lang] || lang}
theme={undefined}
>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<pre className={className} style={style}>
{tokens.map((line, i) => (
<div
key={String(i)}
className={classNames({
highlighted: highlightLines.includes(i + 1),
wrap: themeConfig.showLineNum,
})}
>
{themeConfig.showLineNum && (
<span className="token-line-num">{i + 1}</span>
)}
<div
{...getLineProps({
line,
key: i,
})}
className={classNames({
'line-cell': themeConfig.showLineNum,
})}
>
{line.map((token, key) => (
// getTokenProps 返回值包含 key
// eslint-disable-next-line react/jsx-key
<span {...getTokenProps({ token, key })} />
))}
</div>
</div>
))}
</pre>
)}
</Highlight>
);

return (
<div className="dumi-default-source-code">
<CopyToClipboard
Expand All @@ -62,45 +105,16 @@ const SourceCode: FC<SourceCodeProps> = (props) => {
{isCopied ? <IconCheck /> : <IconCopy />}
</button>
</CopyToClipboard>
<Highlight
{...defaultProps}
code={children}
language={SIMILAR_DSL[lang] || lang}
theme={undefined}
>
{({ className, style, tokens, getLineProps, getTokenProps }) => (
<pre className={className} style={style}>
{tokens.map((line, i) => (
<div
key={String(i)}
className={classNames({
highlighted: highlightLines.includes(i + 1),
wrap: themeConfig.showLineNum,
})}
>
{themeConfig.showLineNum && (
<span className="token-line-num">{i + 1}</span>
)}
<div
{...getLineProps({
line,
key: i,
})}
className={classNames({
'line-cell': themeConfig.showLineNum,
})}
>
{line.map((token, key) => (
// getTokenProps 返回值包含 key
// eslint-disable-next-line react/jsx-key
<span {...getTokenProps({ token, key })} />
))}
</div>
</div>
))}
</pre>
)}
</Highlight>
{props.textarea ? (
<div className="dumi-default-source-code-scroll-container">
<div className="dumi-default-source-code-scroll-content">
{code}
{props.textarea}
</div>
</div>
) : (
code
)}
{props.extra}
</div>
);
Expand Down
26 changes: 22 additions & 4 deletions src/client/theme-default/slots/SourceCodeEditor/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,34 @@
}

&:focus {
box-shadow: 0 0 0 1px lighten(@c-primary, 20%) inset;

@{dark-selector} & {
box-shadow: 0 0 0 1px darken(@c-primary-dark, 20%) inset;

// for firefox because its selection color is not translucent when color-scheme is dark
&::selection {
background-color: fade(@c-primary-dark, 30%);
}
}
}
}

&::after {
content: '';
position: absolute;
z-index: 0;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
}

&:focus-within {
&::after {
box-shadow: 0 0 0 1px @c-primary inset;

@{dark-selector} & {
box-shadow: 0 0 0 1px @c-primary-dark inset;
}
}
}
}
66 changes: 32 additions & 34 deletions src/client/theme-default/slots/SourceCodeEditor/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,45 +51,43 @@ const SourceCodeEditor: FC<ISourceCodeEditorProps> = (props) => {
<div className="dumi-default-source-code-editor" ref={elm}>
<SourceCode
{...props}
extra={
textarea={
style && (
<>
<textarea
className="dumi-default-source-code-editor-textarea"
style={style}
value={code}
onChange={(ev) => {
setCode(ev.target.value);
props.onChange?.(ev.target.value);
// FIXME: remove before publish
props.onTranspile?.({ err: null, code: ev.target.value });
}}
onKeyDown={(ev) => {
// support tab to space
if (ev.key === 'Tab') {
ev.preventDefault();
<textarea
className="dumi-default-source-code-editor-textarea"
style={style}
value={code}
onChange={(ev) => {
setCode(ev.target.value);
props.onChange?.(ev.target.value);
// FIXME: remove before publish
props.onTranspile?.({ err: null, code: ev.target.value });
}}
onKeyDown={(ev) => {
// support tab to space
if (ev.key === 'Tab') {
ev.preventDefault();

const elm = ev.currentTarget;
const { selectionStart: start, selectionEnd: end } = elm;
const before = elm.value.substring(0, start);
const after = elm.value.substring(end);
const spaces = ' ';
const pos = spaces.length + start;
const elm = ev.currentTarget;
const { selectionStart: start, selectionEnd: end } = elm;
const before = elm.value.substring(0, start);
const after = elm.value.substring(end);
const spaces = ' ';
const pos = spaces.length + start;

setCode(`${before}${spaces}${after}`);
setTimeout(() => {
elm.setSelectionRange(pos, pos);
});
}
}}
autoComplete="off"
autoCorrect="off"
autoSave="off"
/>
{props.extra}
</>
setCode(`${before}${spaces}${after}`);
setTimeout(() => {
elm.setSelectionRange(pos, pos);
});
}
}}
autoComplete="off"
autoCorrect="off"
autoSave="off"
/>
)
}
extra={style && props.extra}
>
{code}
</SourceCode>
Expand Down

0 comments on commit eb7f122

Please sign in to comment.