Skip to content

Commit

Permalink
docs: fix playground tabbing and add copy button (#6608)
Browse files Browse the repository at this point in the history
* docs: fix playground tabbing and add copy button

* missed file
  • Loading branch information
kyletsang committed Apr 26, 2023
1 parent bdb4f8d commit 4c84daa
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 8 deletions.
16 changes: 16 additions & 0 deletions www/src/theme/Playground/EditorInfoMessage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import clsx from 'clsx';
import styles from './styles.module.css';

const EditorInfoMessage: React.FC<React.HTMLAttributes<HTMLDivElement>> = (
props,
) => (
<div
className={clsx('alert alert-info p-2', styles.editorInfoMessage)}
{...props}
/>
);

EditorInfoMessage.displayName = 'EditorInfoMessage';

export default EditorInfoMessage;
94 changes: 86 additions & 8 deletions www/src/theme/Playground/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React from 'react';
import React, { useCallback, useContext, useRef, useState } from 'react';
import clsx from 'clsx';
import useIsBrowser from '@docusaurus/useIsBrowser';
import { LiveProvider, LiveEditor, LiveError } from 'react-live';
import { LiveContext, LiveProvider, LiveEditor, LiveError } from 'react-live';
import Translate from '@docusaurus/Translate';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import BrowserOnly from '@docusaurus/BrowserOnly';
import { usePrismTheme } from '@docusaurus/theme-common';
import type { Props } from '@theme/Playground';
import type { ThemeConfig } from '@docusaurus/theme-live-codeblock';
import CopyButton from '@theme-original/CodeBlock/CopyButton';
import Preview from './Preview';
import EditorInfoMessage from './EditorInfoMessage';

import styles from './styles.module.css';

Expand Down Expand Up @@ -47,15 +49,91 @@ function ResultWithHeader({ className }: any) {
);
}

let uid = 0;

function ThemedLiveEditor() {
const { code } = useContext(LiveContext);
const isBrowser = useIsBrowser();
const [focused, setFocused] = useState(false);
const [ignoreTab, setIgnoreTab] = useState(false);
const [keyboardFocused, setKeyboardFocused] = useState(false);
const mouseDownRef = useRef(false);
const idRef = useRef(null);

if (idRef.current === null) idRef.current = `described-by-${++uid}`;
const id = idRef.current;

const handleKeyDown = useCallback(
(e) => {
if (ignoreTab) {
if (e.key !== 'Tab' && e.key !== 'Shift') {
if (e.key === 'Enter') e.preventDefault();
setIgnoreTab(false);
}
} else if (e.key === 'Escape') {
setIgnoreTab(true);
}
},
[ignoreTab],
);

const handleFocus = useCallback(() => {
setFocused(true);
setIgnoreTab(!mouseDownRef.current);
setKeyboardFocused(!mouseDownRef.current);
}, []);

const handleBlur = useCallback(() => {
setFocused(false);
}, []);

const handleMouseDown = useCallback(() => {
mouseDownRef.current = true;
window.setTimeout(() => {
mouseDownRef.current = false;
});
}, []);

// Hack because LiveEditor doesn't define this type
const props = {
ignoreTabKey: ignoreTab,
};

const showMessage = keyboardFocused || (focused && !ignoreTab);

return (
<LiveEditor
// We force remount the editor on hydration,
// otherwise dark prism theme is not applied
key={String(isBrowser)}
className={styles.playgroundEditor}
/>
<div className="position-relative">
<LiveEditor
// We force remount the editor on hydration,
// otherwise dark prism theme is not applied
key={String(isBrowser)}
className={styles.playgroundEditor}
onFocus={handleFocus}
onBlur={handleBlur}
onKeyDown={handleKeyDown}
onMouseDown={handleMouseDown}
aria-describedby={showMessage ? id : null}
{...props}
/>
<div className={clsx(styles.editorToolbar)}>
{showMessage && (
<EditorInfoMessage id={id} aria-live="polite">
{ignoreTab ? (
<>
Press <kbd>enter</kbd> or type a key to enable tab-to-indent
</>
) : (
<>
Press <kbd>esc</kbd> to disable tab trapping
</>
)}
</EditorInfoMessage>
)}
<div className={styles.buttonGroup}>
<CopyButton code={code} />
</div>
</div>
</div>
);
}

Expand Down
27 changes: 27 additions & 0 deletions www/src/theme/Playground/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,30 @@
padding: 1rem;
background-color: var(--ifm-pre-background);
}

.editorToolbar {
position: absolute;
right: calc(var(--ifm-pre-padding) / 2);
top: calc(var(--ifm-pre-padding) / 2);
display: flex;
column-gap: 0.2rem;
}

.editorInfoMessage {
font-size: 70%;
pointer-events: none;
}

/* https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-classic/src/theme/CodeBlock/Content/styles.module.css */
.buttonGroup button {
display: flex;
align-items: center;
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 var(--ifm-transition-fast) ease-in-out;
opacity: 1;
}

0 comments on commit 4c84daa

Please sign in to comment.