diff --git a/src/app/plugins/react-custom-html-parser.tsx b/src/app/plugins/react-custom-html-parser.tsx index cd683e36..057b0dff 100644 --- a/src/app/plugins/react-custom-html-parser.tsx +++ b/src/app/plugins/react-custom-html-parser.tsx @@ -1,5 +1,11 @@ /* eslint-disable jsx-a11y/alt-text */ -import React, { ComponentPropsWithoutRef, ReactEventHandler, Suspense, lazy } from 'react'; +import React, { + ComponentPropsWithoutRef, + ReactEventHandler, + Suspense, + lazy, + useState, +} from 'react'; import { Element, Text as DOMText, @@ -9,10 +15,11 @@ import { } from 'html-react-parser'; import { MatrixClient } from 'matrix-js-sdk'; 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 Linkify from 'linkify-react'; import { ErrorBoundary } from 'react-error-boundary'; +import { ChildNode } from 'domhandler'; import * as css from '../styles/CustomHtml.css'; import { getMxIdLocalPart, @@ -31,7 +38,7 @@ import { testMatrixTo, } from './matrix-to'; import { onEnterOrSpace } from '../utils/keyboard'; -import { tryDecodeURIComponent } from '../utils/dom'; +import { copyToClipboard, tryDecodeURIComponent } from '../utils/dom'; 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 + <> +
+ { + handleCopyClick(); + }} + > + + + { + setCollapsed(!collapsed); + }} + > + + +
+ +
{domToReact(children, opts)}
+
+ + ); +} + export const getReactCustomHtmlParser = ( mx: MatrixClient, roomId: string | undefined, @@ -270,16 +321,9 @@ export const getReactCustomHtmlParser = ( if (name === 'pre') { return ( - - -
{domToReact(children, opts)}
-
+ //SHOULD ALL OF THIS BE IN A renderCodeBlock function? not text, but one layr down + + {CodeBlock(children, opts)} ); } diff --git a/src/app/styles/CustomHtml.css.ts b/src/app/styles/CustomHtml.css.ts index d86a3236..95cb6dc5 100644 --- a/src/app/styles/CustomHtml.css.ts +++ b/src/app/styles/CustomHtml.css.ts @@ -87,8 +87,33 @@ export const CodeBlock = style([ fontStyle: 'normal', }, ]); -export const CodeBlockInternal = style({ - padding: `${config.space.S200} ${config.space.S200} 0`, +export const CodeBlockInternal = recipe({ + 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([