From 7b99bd71da105824774bec33ceb5947cc93a9dee Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Thu, 25 Apr 2024 11:36:58 -0700 Subject: [PATCH] Update overlay buttons --- src/modules/blocks/RenderHtml.tsx | 12 +-- src/modules/blocks/RenderImage.tsx | 14 ++-- src/modules/blocks/code/ButtonCodePen.tsx | 8 +- src/modules/blocks/code/ButtonJSFiddle.tsx | 8 +- src/modules/blocks/code/ButtonStackBlitz.tsx | 8 +- src/modules/blocks/code/RenderCode.tsx | 78 ++++++++++++-------- 6 files changed, 76 insertions(+), 52 deletions(-) diff --git a/src/modules/blocks/RenderHtml.tsx b/src/modules/blocks/RenderHtml.tsx index ce32a428b..672b9e169 100644 --- a/src/modules/blocks/RenderHtml.tsx +++ b/src/modules/blocks/RenderHtml.tsx @@ -1,14 +1,14 @@ import * as React from 'react'; import type { SxProps } from '@mui/joy/styles/types'; -import { Box, Button, IconButton, Tooltip, Typography } from '@mui/joy'; +import { Box, Button, Tooltip, Typography } from '@mui/joy'; import ContentCopyIcon from '@mui/icons-material/ContentCopy'; import WebIcon from '@mui/icons-material/Web'; import { copyToClipboard } from '~/common/util/clipboardUtils'; import type { HtmlBlock } from './blocks'; -import { overlayButtonsSx } from './code/RenderCode'; +import { OverlayButton, overlayButtonsSx } from './code/RenderCode'; // this is used by the blocks parser (for full text detection) and by the Code component (for inline rendering) @@ -99,14 +99,14 @@ export function RenderHtml(props: { htmlBlock: HtmlBlock, sx?: SxProps }) { {/* External HTML Buttons */} - setShowHTML(!showHTML)}> + setShowHTML(!showHTML)}> - + - + - + diff --git a/src/modules/blocks/RenderImage.tsx b/src/modules/blocks/RenderImage.tsx index a52d313be..f6f4927a1 100644 --- a/src/modules/blocks/RenderImage.tsx +++ b/src/modules/blocks/RenderImage.tsx @@ -12,7 +12,7 @@ import { GoodTooltip } from '~/common/components/GoodTooltip'; import { Link } from '~/common/components/Link'; import type { ImageBlock } from './blocks'; -import { overlayButtonsSx } from './code/RenderCode'; +import { OverlayButton, overlayButtonsSx } from './code/RenderCode'; const mdImageReferenceRegex = /^!\[([^\]]*)]\(([^)]+)\)$/; @@ -128,24 +128,24 @@ export const RenderImage = (props: { {!!props.onRunAgain && ( - + - + )} {!!alt && ( - setInfoOpen(open => !open)}> + setInfoOpen(open => !open)}> - + )} - + - + diff --git a/src/modules/blocks/code/ButtonCodePen.tsx b/src/modules/blocks/code/ButtonCodePen.tsx index e591786ea..69310bf07 100644 --- a/src/modules/blocks/code/ButtonCodePen.tsx +++ b/src/modules/blocks/code/ButtonCodePen.tsx @@ -1,11 +1,13 @@ import * as React from 'react'; -import { IconButton, Tooltip } from '@mui/joy'; +import { Tooltip } from '@mui/joy'; import { Brand } from '~/common/app.config'; import { CodePenIcon } from '~/common/components/icons/3rdparty/CodePenIcon'; import { prettyTimestampForFilenames } from '~/common/util/timeUtils'; +import { OverlayButton } from './RenderCode'; + // CodePen is a web-based HTML, CSS, and JavaScript code editor const _languages = ['html', 'css', 'javascript', 'json', 'typescript']; @@ -48,9 +50,9 @@ const handleOpenInCodePen = (code: string, language: string) => { export function ButtonCodePen(props: { code: string, language: string }): React.JSX.Element { return ( - handleOpenInCodePen(props.code, props.language)}> + handleOpenInCodePen(props.code, props.language)}> - + ); } \ No newline at end of file diff --git a/src/modules/blocks/code/ButtonJSFiddle.tsx b/src/modules/blocks/code/ButtonJSFiddle.tsx index f55e1aa45..9119d943a 100644 --- a/src/modules/blocks/code/ButtonJSFiddle.tsx +++ b/src/modules/blocks/code/ButtonJSFiddle.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; -import { IconButton, Tooltip } from '@mui/joy'; +import { Tooltip } from '@mui/joy'; + +import { OverlayButton } from './RenderCode'; // JSFiidle is a web-based HTML, CSS, and JavaScript code editor @@ -49,9 +51,9 @@ const handleOpenInJsFiddle = (code: string, language: string) => { export function ButtonJsFiddle(props: { code: string, language: string }): React.JSX.Element { return ( - handleOpenInJsFiddle(props.code, props.language)}> + handleOpenInJsFiddle(props.code, props.language)}> JS - + ); } \ No newline at end of file diff --git a/src/modules/blocks/code/ButtonStackBlitz.tsx b/src/modules/blocks/code/ButtonStackBlitz.tsx index 7ad30a4d7..6b88c8c61 100644 --- a/src/modules/blocks/code/ButtonStackBlitz.tsx +++ b/src/modules/blocks/code/ButtonStackBlitz.tsx @@ -1,11 +1,13 @@ import * as React from 'react'; -import { IconButton, Tooltip } from '@mui/joy'; +import { Tooltip } from '@mui/joy'; import { Brand } from '~/common/app.config'; import { StackBlitzIcon } from '~/common/components/icons/3rdparty/StackBlitzIcon'; import { prettyTimestampForFilenames } from '~/common/util/timeUtils'; +import { OverlayButton } from './RenderCode'; + const _languages = [ 'typescript', @@ -77,9 +79,9 @@ const handleOpenInStackBlitz = (code: string, language: string, title?: string) export function ButtonStackBlitz(props: { code: string, language: string, title?: string }): React.JSX.Element { return ( - handleOpenInStackBlitz(props.code, props.language, props.title)}> + handleOpenInStackBlitz(props.code, props.language, props.title)}> - + ); } diff --git a/src/modules/blocks/code/RenderCode.tsx b/src/modules/blocks/code/RenderCode.tsx index 896056657..7a9a34aec 100644 --- a/src/modules/blocks/code/RenderCode.tsx +++ b/src/modules/blocks/code/RenderCode.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { useQuery } from '@tanstack/react-query'; import type { SxProps } from '@mui/joy/styles/types'; -import { Box, ButtonGroup, IconButton, Sheet, Tooltip, Typography } from '@mui/joy'; +import { Box, ButtonGroup, IconButton, Sheet, styled, Tooltip, Typography } from '@mui/joy'; import ContentCopyIcon from '@mui/icons-material/ContentCopy'; import FitScreenIcon from '@mui/icons-material/FitScreen'; import HtmlIcon from '@mui/icons-material/Html'; @@ -19,11 +19,13 @@ import { ButtonStackBlitz, isStackBlitzSupported } from './ButtonStackBlitz'; import { heuristicIsHtml, IFrameComponent } from '../RenderHtml'; import { patchSvgString, RenderCodeMermaid } from './RenderCodeMermaid'; + export function getPlantUmlServerUrl(): string { // set at nextjs build time return process.env.NEXT_PUBLIC_PLANTUML_SERVER_URL || 'https://www.plantuml.com/plantuml/svg/'; } + async function fetchPlantUmlSvg(plantUmlCode: string): Promise { // Get the PlantUML server from inline env var let plantUmlServerUrl = getPlantUmlServerUrl(); @@ -64,13 +66,19 @@ async function fetchPlantUmlSvg(plantUmlCode: string): Promise { } +export const OverlayButton = styled(IconButton)(({ theme, variant }) => ({ + backgroundColor: variant === 'outlined' ? theme.palette.background.surface : undefined, + '--Icon-fontSize': theme.fontSize.lg, +})) as typeof IconButton; + + export const overlayButtonsSx: SxProps = { position: 'absolute', top: 0, right: 0, zIndex: 2, /* top of message and its chips */ display: 'flex', flexDirection: 'row', gap: 1, opacity: 0, transition: 'opacity 0.2s cubic-bezier(.17,.84,.44,1)', // buttongroup: background '& > div > button': { - backgroundColor: 'background.surface', + // backgroundColor: 'background.surface', // backdropFilter: 'blur(12px)', }, }; @@ -206,53 +214,63 @@ function RenderCodeImpl(props: RenderCodeImplProps) { {/* Buttons */} + {/* Show HTML */} {isHTML && ( - setShowHTML(!showHTML)}> - - - - )} - {isMermaid && ( - - setShowMermaid(!showMermaid)}> - - - - )} - {isPlantUML && ( - - setShowPlantUML(!showPlantUML)}> - - + setShowHTML(!showHTML)}> + + )} + + {/* Show SVG */} {isSVG && ( - setShowSVG(!showSVG)}> + setShowSVG(!showSVG)}> - + )} - {((isMermaid && showMermaid) || (isPlantUML && showPlantUML && !plantUmlError) || (isSVG && showSVG && canScaleSVG)) && ( - - setFitScreen(on => !on)}> - - - + + {/* Show Diagrams */} + {(isMermaid || isPlantUML) && ( + + {/* Toggle rendering */} + + { + if (isMermaid) setShowMermaid(on => !on); + if (isPlantUML) setShowPlantUML(on => !on); + }}> + + + + + {/* Fit-To-Screen */} + {((isMermaid && showMermaid) || (isPlantUML && showPlantUML && !plantUmlError) || (isSVG && showSVG && canScaleSVG)) && ( + + setFitScreen(on => !on)}> + + + + )} + )} + + {/* New Code Window Buttons */} {(canJSFiddle || canCodePen || canStackBlitz) && ( - + {canJSFiddle && } {canCodePen && } {canStackBlitz && } )} + + {/* Copy */} {props.noCopyButton !== true && ( - + - + )}