From 97e69228ffff87c42f10c1c43cdc31830915cc50 Mon Sep 17 00:00:00 2001 From: Alexey Pyltsyn Date: Sat, 16 Apr 2022 11:11:58 +0300 Subject: [PATCH] Fixes --- .../src/theme-classic.d.ts | 10 ++++ .../src/theme/CodeBlock/Content/String.tsx | 18 ++++++- .../theme/CodeBlock/Content/styles.module.css | 25 ++++++---- .../CodeBlock/CopyButton/styles.module.css | 17 ------- .../theme/CodeBlock/WordWrapButton/index.tsx | 34 ++----------- .../src/hooks/useCodeWordWrap.ts | 48 +++++++++++++++++++ packages/docusaurus-theme-common/src/index.ts | 1 + 7 files changed, 95 insertions(+), 58 deletions(-) create mode 100644 packages/docusaurus-theme-common/src/hooks/useCodeWordWrap.ts diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts index d88f3f647166..b5a98b4b1e9b 100644 --- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts +++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts @@ -221,6 +221,16 @@ declare module '@theme/CodeBlock/Line' { export default function CodeBlockLine(props: Props): JSX.Element; } +declare module '@theme/CodeBlock/WordWrapButton' { + export interface Props { + readonly className?: string; + readonly onClick: React.MouseEventHandler; + readonly isEnabled: boolean; + } + + export default function WordWrapButton(props: Props): JSX.Element; +} + declare module '@theme/DocCard' { import type {PropSidebarItem} from '@docusaurus/plugin-content-docs'; diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx index d4e59b1718c5..acf289c926b2 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React from 'react'; +import React, {useRef} from 'react'; import { useThemeConfig, parseCodeBlockTitle, @@ -13,11 +13,13 @@ import { parseLines, containsLineNumbers, usePrismTheme, + useCodeWordWrap, } from '@docusaurus/theme-common'; import clsx from 'clsx'; import Highlight, {defaultProps, type Language} from 'prism-react-renderer'; import Line from '@theme/CodeBlock/Line'; import CopyButton from '@theme/CodeBlock/CopyButton'; +import WordWrapButton from '@theme/CodeBlock/WordWrapButton'; import Container from '@theme/CodeBlock/Container'; import type {Props} from '@theme/CodeBlock/Content/String'; @@ -37,6 +39,8 @@ export default function CodeBlockString({ const language = languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage; const prismTheme = usePrismTheme(); + const codeBlockRef = useRef(null); + const wordWrap = useCodeWordWrap(codeBlockRef); // We still parse the metastring in case we want to support more syntax in the // future. Note that MDX doesn't strip quotes when parsing metastring: @@ -67,6 +71,7 @@ export default function CodeBlockString({
               
           )}
         
-        
+        
+ {(wordWrap.isEnabled || wordWrap.isCodeScrollable) && ( + wordWrap.toggle()} + isEnabled={wordWrap.isEnabled} + /> + )} + +
); diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/styles.module.css b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/styles.module.css index 6f68e4864e45..f1c1e97728fb 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/styles.module.css @@ -55,28 +55,35 @@ } } -.codeButton { - --docusaurus-code-button-size: 2rem; +.buttonGroup { + display: flex; position: absolute; right: calc(var(--ifm-pre-padding) / 2); top: calc(var(--ifm-pre-padding) / 2); - width: var(--docusaurus-code-button-size); - height: var(--docusaurus-code-button-size); +} + +.buttonGroup button { display: flex; - justify-content: center; align-items: center; - background: inherit; + background: var(--prism-background-color); + color: var(--prism-color); border: 1px solid var(--ifm-color-emphasis-300); border-radius: var(--ifm-global-radius); + padding: 0.4rem; + line-height: 0; transition: opacity 200ms ease-in-out; opacity: 0; } -.codeButton:focus-visible, -.codeButton:hover { +.buttonGroup button:not(:first-child) { + margin-left: 0.5rem; +} + +.buttonGroup button:focus-visible, +.buttonGroup button:hover { opacity: 1 !important; } -:global(.theme-code-block:hover) .codeButton { +:global(.theme-code-block:hover) .buttonGroup button { opacity: 0.4; } diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/CopyButton/styles.module.css b/packages/docusaurus-theme-classic/src/theme/CodeBlock/CopyButton/styles.module.css index 3992fc7387ed..776c1960b58f 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/CopyButton/styles.module.css +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/CopyButton/styles.module.css @@ -5,23 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -.copyButton { - display: flex; - /* TODO: move to base button styling */ - background: var(--prism-background-color); - color: var(--prism-color); - border: 1px solid var(--ifm-color-emphasis-300); - border-radius: var(--ifm-global-radius); - padding: 0.4rem; - position: absolute; - right: calc(var(--ifm-pre-padding) / 2); - top: calc(var(--ifm-pre-padding) / 2); - transition: opacity 200ms ease-in-out; - opacity: 0; -} - -.copyButton:focus-visible, -.copyButton:hover, :global(.theme-code-block:hover) .copyButtonCopied { opacity: 1 !important; } diff --git a/packages/docusaurus-theme-classic/src/theme/CodeBlock/WordWrapButton/index.tsx b/packages/docusaurus-theme-classic/src/theme/CodeBlock/WordWrapButton/index.tsx index 5432d515ecef..1cd66a7d2fe2 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/WordWrapButton/index.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/WordWrapButton/index.tsx @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import React, {useCallback, useState, useEffect} from 'react'; +import React from 'react'; import clsx from 'clsx'; import {translate} from '@docusaurus/Translate'; import type {Props} from '@theme/CodeBlock/WordWrapButton'; @@ -13,21 +13,10 @@ import type {Props} from '@theme/CodeBlock/WordWrapButton'; import styles from './styles.module.css'; export default function WordWrapButton({ - codeBlockRef, className, + onClick, + isEnabled, }: Props): JSX.Element | null { - const [isEnabled, setIsEnabled] = useState(false); - const [isCodeScrollable, setIsCodeScrollable] = useState(false); - const toggleWordWrapCode = useCallback(() => { - setIsEnabled((value) => !value); - - const codeElement = codeBlockRef.current!.querySelector('code'); - codeElement?.classList.toggle(styles.codeWithWordWrap!); - }, [codeBlockRef]); - const updateCodeIsScrollable = useCallback(() => { - const {scrollWidth, clientWidth} = codeBlockRef.current!; - setIsCodeScrollable(scrollWidth > clientWidth); - }, [codeBlockRef]); const title = translate({ id: 'theme.CodeBlock.wordWrapToggle', message: 'Toggle word wrap', @@ -35,25 +24,10 @@ export default function WordWrapButton({ 'The title attribute for toggle word wrapping button of code block lines', }); - useEffect(() => { - updateCodeIsScrollable(); - - window.addEventListener('resize', updateCodeIsScrollable); - - return () => { - window.removeEventListener('resize', updateCodeIsScrollable); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - if (!isCodeScrollable) { - return null; - } - return (