mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-04 22:40:29 +03:00
add buttons to codeblocks
This commit is contained in:
parent
e6f4eeca8e
commit
96331090c5
2 changed files with 84 additions and 15 deletions
|
|
@ -1,5 +1,11 @@
|
||||||
/* eslint-disable jsx-a11y/alt-text */
|
/* eslint-disable jsx-a11y/alt-text */
|
||||||
import React, { ComponentPropsWithoutRef, ReactEventHandler, Suspense, lazy } from 'react';
|
import React, {
|
||||||
|
ComponentPropsWithoutRef,
|
||||||
|
ReactEventHandler,
|
||||||
|
Suspense,
|
||||||
|
lazy,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
import {
|
import {
|
||||||
Element,
|
Element,
|
||||||
Text as DOMText,
|
Text as DOMText,
|
||||||
|
|
@ -9,10 +15,11 @@ import {
|
||||||
} from 'html-react-parser';
|
} from 'html-react-parser';
|
||||||
import { MatrixClient } from 'matrix-js-sdk';
|
import { MatrixClient } from 'matrix-js-sdk';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { Scroll, Text } from 'folds';
|
import { Icon, IconButton, Icons, Scroll, Text } from 'folds';
|
||||||
import { IntermediateRepresentation, Opts as LinkifyOpts, OptFn } from 'linkifyjs';
|
import { IntermediateRepresentation, Opts as LinkifyOpts, OptFn } from 'linkifyjs';
|
||||||
import Linkify from 'linkify-react';
|
import Linkify from 'linkify-react';
|
||||||
import { ErrorBoundary } from 'react-error-boundary';
|
import { ErrorBoundary } from 'react-error-boundary';
|
||||||
|
import { ChildNode } from 'domhandler';
|
||||||
import * as css from '../styles/CustomHtml.css';
|
import * as css from '../styles/CustomHtml.css';
|
||||||
import {
|
import {
|
||||||
getMxIdLocalPart,
|
getMxIdLocalPart,
|
||||||
|
|
@ -31,7 +38,7 @@ import {
|
||||||
testMatrixTo,
|
testMatrixTo,
|
||||||
} from './matrix-to';
|
} from './matrix-to';
|
||||||
import { onEnterOrSpace } from '../utils/keyboard';
|
import { onEnterOrSpace } from '../utils/keyboard';
|
||||||
import { tryDecodeURIComponent } from '../utils/dom';
|
import { copyToClipboard, tryDecodeURIComponent } from '../utils/dom';
|
||||||
|
|
||||||
const ReactPrism = lazy(() => import('./react-prism/ReactPrism'));
|
const ReactPrism = lazy(() => import('./react-prism/ReactPrism'));
|
||||||
|
|
||||||
|
|
@ -195,6 +202,50 @@ export const highlightText = (
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function CodeBlock(children: ChildNode[], opts: HTMLReactParserOptions) {
|
||||||
|
const [copied, setCopied] = useState(false);
|
||||||
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
|
|
||||||
|
//HANDLECOPY FUNCTION HERE?
|
||||||
|
const handleCopyClick = () => {
|
||||||
|
//const codeText = extractTextFromChildren(children); // IDK HOW THIS SHOULD BE DONE
|
||||||
|
//copyToClipboard(codeText);
|
||||||
|
|
||||||
|
setCopied(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
// Probably need a better copy icon
|
||||||
|
<>
|
||||||
|
<div className={css.CodeBlockControls}>
|
||||||
|
<IconButton
|
||||||
|
variant="Secondary"
|
||||||
|
size="300"
|
||||||
|
radii="300"
|
||||||
|
onClick={() => {
|
||||||
|
handleCopyClick();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon src={copied ? Icons.Check : Icons.File} size="50" />
|
||||||
|
</IconButton>
|
||||||
|
<IconButton
|
||||||
|
variant="Secondary" // Collapse - how to show icon even when not hovering if collapsed?
|
||||||
|
size="300" //This should be somewhat persistent - how?
|
||||||
|
radii="300"
|
||||||
|
onClick={() => {
|
||||||
|
setCollapsed(!collapsed);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon src={collapsed ? Icons.ChevronRight : Icons.ChevronBottom} size="50" />
|
||||||
|
</IconButton>
|
||||||
|
</div>
|
||||||
|
<Scroll direction="Horizontal" variant="Secondary" size="300" visibility="Hover" hideTrack>
|
||||||
|
<div className={css.CodeBlockInternal({ collapsed })}>{domToReact(children, opts)}</div>
|
||||||
|
</Scroll>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export const getReactCustomHtmlParser = (
|
export const getReactCustomHtmlParser = (
|
||||||
mx: MatrixClient,
|
mx: MatrixClient,
|
||||||
roomId: string | undefined,
|
roomId: string | undefined,
|
||||||
|
|
@ -270,16 +321,9 @@ export const getReactCustomHtmlParser = (
|
||||||
|
|
||||||
if (name === 'pre') {
|
if (name === 'pre') {
|
||||||
return (
|
return (
|
||||||
<Text {...props} as="pre" className={css.CodeBlock}>
|
//SHOULD ALL OF THIS BE IN A renderCodeBlock function? not text, but one layr down
|
||||||
<Scroll
|
<Text {...props} as="pre" className={css.CodeBlock} style={{ position: 'relative' }}>
|
||||||
direction="Horizontal"
|
{CodeBlock(children, opts)}
|
||||||
variant="Secondary"
|
|
||||||
size="300"
|
|
||||||
visibility="Hover"
|
|
||||||
hideTrack
|
|
||||||
>
|
|
||||||
<div className={css.CodeBlockInternal}>{domToReact(children, opts)}</div>
|
|
||||||
</Scroll>
|
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,8 +87,33 @@ export const CodeBlock = style([
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
export const CodeBlockInternal = style({
|
export const CodeBlockInternal = recipe({
|
||||||
padding: `${config.space.S200} ${config.space.S200} 0`,
|
base: [
|
||||||
|
DefaultReset,
|
||||||
|
{
|
||||||
|
padding: `${config.space.S200} ${config.space.S200} 0`,
|
||||||
|
minWidth: config.size.ModalDrawerWidth,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
variants: {
|
||||||
|
collapsed: {
|
||||||
|
true: {
|
||||||
|
maxHeight: config.space.S700, // should controls (collapse) be visible when collapsed? - yes, what's the best way to do this?
|
||||||
|
overflow: 'hidden', // collapse should also only be visible if the doc has more than 1 line
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
export const CodeBlockControls = style({
|
||||||
|
position: 'absolute',
|
||||||
|
top: config.space.S200,
|
||||||
|
right: config.space.S200,
|
||||||
|
display: 'none',
|
||||||
|
selectors: {
|
||||||
|
[`${CodeBlock}:hover &`]: {
|
||||||
|
display: 'inline',
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const List = style([
|
export const List = style([
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue