From 2251be07dba902afd2b3f6cfe9c0359c29e0abe4 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 27 Sep 2023 16:20:38 +0200 Subject: [PATCH 1/2] wip: localstorage state --- .../src/hooks/useCodeWordWrap.ts | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/docusaurus-theme-common/src/hooks/useCodeWordWrap.ts b/packages/docusaurus-theme-common/src/hooks/useCodeWordWrap.ts index 12cf2eff4c8d..c723e2d5d862 100644 --- a/packages/docusaurus-theme-common/src/hooks/useCodeWordWrap.ts +++ b/packages/docusaurus-theme-common/src/hooks/useCodeWordWrap.ts @@ -6,6 +6,7 @@ */ import type {RefObject} from 'react'; import {useState, useCallback, useEffect, useRef} from 'react'; +import {useStorageSlot} from '../index'; import {useMutationObserver} from './useMutationObserver'; // Callback fires when the "hidden" attribute of a tabpanel changes @@ -58,14 +59,14 @@ export function useCodeWordWrap(): { readonly isCodeScrollable: boolean; readonly toggle: () => void; } { - const [isEnabled, setIsEnabled] = useState(false); + const [value, storageSlot] = useStorageSlot('docusaurus.code.wordWrap'); const [isCodeScrollable, setIsCodeScrollable] = useState(false); const codeBlockRef = useRef(null); const toggle = useCallback(() => { const codeElement = codeBlockRef.current!.querySelector('code')!; - if (isEnabled) { + if (value === 'true') { codeElement.removeAttribute('style'); } else { codeElement.style.whiteSpace = 'pre-wrap'; @@ -74,8 +75,8 @@ export function useCodeWordWrap(): { codeElement.style.overflowWrap = 'anywhere'; } - setIsEnabled((value) => !value); - }, [codeBlockRef, isEnabled]); + storageSlot.set(value === 'true' ? 'false' : 'true'); + }, [codeBlockRef, value, storageSlot]); const updateCodeIsScrollable = useCallback(() => { const {scrollWidth, clientWidth} = codeBlockRef.current!; @@ -89,7 +90,7 @@ export function useCodeWordWrap(): { useEffect(() => { updateCodeIsScrollable(); - }, [isEnabled, updateCodeIsScrollable]); + }, [value, updateCodeIsScrollable]); useEffect(() => { window.addEventListener('resize', updateCodeIsScrollable, { @@ -101,5 +102,5 @@ export function useCodeWordWrap(): { }; }, [updateCodeIsScrollable]); - return {codeBlockRef, isEnabled, isCodeScrollable, toggle}; + return {codeBlockRef, isEnabled: value === 'true', isCodeScrollable, toggle}; } From 86ea3947ca6fdf61f603de92f2151f30a0fbfed2 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Thu, 28 Sep 2023 18:03:42 +0200 Subject: [PATCH 2/2] refactor: sync wrap states in localstorage --- .../src/theme/CodeBlock/Content/String.tsx | 1 + .../src/hooks/useCodeWordWrap.ts | 38 ++++++++++--------- 2 files changed, 22 insertions(+), 17 deletions(-) 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 6a051802e2ef..122b14489dd0 100644 --- a/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx +++ b/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/String.tsx @@ -85,6 +85,7 @@ export default function CodeBlockString({ ref={wordWrap.codeBlockRef} className={clsx(className, styles.codeBlock, 'thin-scrollbar')}> { + const newValue = value === 'true' ? 'false' : 'true'; + storageSlot.set(newValue); + }, [value, storageSlot]); + + return [value === 'true', toggle] as const; +} + export function useCodeWordWrap(): { readonly codeBlockRef: RefObject; readonly isEnabled: boolean; readonly isCodeScrollable: boolean; readonly toggle: () => void; + readonly codeStyle: CSSProperties; } { - const [value, storageSlot] = useStorageSlot('docusaurus.code.wordWrap'); + const [isEnabled, toggleWrap] = useCodeWrapState(); const [isCodeScrollable, setIsCodeScrollable] = useState(false); const codeBlockRef = useRef(null); + const codeStyle: CSSProperties = isEnabled + ? {whiteSpace: 'pre-wrap', overflowWrap: 'anywhere'} + : {}; const toggle = useCallback(() => { - const codeElement = codeBlockRef.current!.querySelector('code')!; - - if (value === 'true') { - codeElement.removeAttribute('style'); - } else { - codeElement.style.whiteSpace = 'pre-wrap'; - // When code wrap is enabled, we want to avoid a scrollbar in any case - // Ensure that very very long words/strings/tokens still wrap - codeElement.style.overflowWrap = 'anywhere'; - } - - storageSlot.set(value === 'true' ? 'false' : 'true'); - }, [codeBlockRef, value, storageSlot]); + toggleWrap(); + }, [toggleWrap]); const updateCodeIsScrollable = useCallback(() => { const {scrollWidth, clientWidth} = codeBlockRef.current!; @@ -90,7 +94,7 @@ export function useCodeWordWrap(): { useEffect(() => { updateCodeIsScrollable(); - }, [value, updateCodeIsScrollable]); + }, [isEnabled, updateCodeIsScrollable]); useEffect(() => { window.addEventListener('resize', updateCodeIsScrollable, { @@ -102,5 +106,5 @@ export function useCodeWordWrap(): { }; }, [updateCodeIsScrollable]); - return {codeBlockRef, isEnabled: value === 'true', isCodeScrollable, toggle}; + return {codeBlockRef, isEnabled, isCodeScrollable, toggle, codeStyle}; }