docs: redesigned code blocks (#2745)

* docs: redesigned code blocks to include titles

* docs: added a title where necessary
This commit is contained in:
Shahed Nasser
2022-12-08 18:52:54 +02:00
committed by GitHub
parent 8efae2dfcf
commit a57177ded5
60 changed files with 455 additions and 375 deletions
+37 -24
View File
@@ -47,37 +47,23 @@ html[data-theme="dark"] .docusaurus-highlight-code-line {
position: relative;
}
.code-tabs .tabs,
.code-header {
padding: 8px 16px;
padding: 12px 16px;
}
.code-header {
background-color: #161616;
display: flex;
justify-content: flex-end;
justify-content: space-between;
border-radius: var(--ifm-code-border-radius) var(--ifm-code-border-radius) 0px 0px;
}
.code-tabs .tabs {
background-color: transparent;
position: absolute;
top: 0;
left: 0;
z-index: 1;
overflow-x: auto;
backface-visibility: hidden;
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
}
.code-tabs .tabs::-webkit-scrollbar {
display: none;
}
.code-tabs .tabs__item {
color: #6F6F6F;
color: var(--ifm-code-tabs-color);
font-weight: 600;
font-size: 13px;
padding: 0 12px;
@@ -90,6 +76,12 @@ html[data-theme="dark"] .docusaurus-highlight-code-line {
margin-left: 4px;
}
.code-title {
font-size: 13px;
line-height: var(--ifm-line-height-base);
color: var(--ifm-code-title-color);
}
.code-tabs .tabs__item--active {
border-color: #393939;
background-color: var(--ifm-code-tabs-active-bg);
@@ -97,7 +89,8 @@ html[data-theme="dark"] .docusaurus-highlight-code-line {
font-size: 13px;
}
.theme-code-block:not(.no-header-block) {
.theme-code-block:not(.no-header-block),
.code-tabs .theme-code-block {
border-radius: 0 0 var(--ifm-code-border-radius) var(--ifm-code-border-radius) !important;
}
@@ -132,11 +125,11 @@ a.code-action {
width: 20px;
}
.theme-code-block:not(.no-header-block) [class*=buttonGroup] {
/* .theme-code-block:not(.no-header-block) [class*=buttonGroup] {
display: none;
}
} */
.theme-code-block.no-header-block [class*=buttonGroup] button {
.theme-code-block [class*=buttonGroup] button {
opacity: 1 !important;
border: none;
}
@@ -170,9 +163,29 @@ html:not([data-theme="dark"]) .theme-code-block:not(.no-header-block) {
}
@media screen and (min-width: 568px) {
.code-tabs .tabs {
.prism-code {
max-width: 90%;
}
.prism-code:after {
content: '';
position: absolute;
right: 0;
top: 0;
width: calc(10% + 24px);
height: 100%;
background: linear-gradient(90deg, #17171700, #262626 24px);
}
.prism-code:not(:hover)::-webkit-scrollbar-thumb,
.prism-code:not(:hover)::-webkit-scrollbar-track {
visibility: hidden;
}
.prism-code:hover::-webkit-scrollbar-thumb,
.prism-code:hover::-webkit-scrollbar-track {
opacity: 1;
}
}
@media screen and (max-width: 567px) {
@@ -180,7 +193,7 @@ html:not([data-theme="dark"]) .theme-code-block:not(.no-header-block) {
visibility: hidden;
}
.code-tabs .tabs {
max-width: 100%;
.tablist-wrapper.code-header .code-title {
display: none;
}
}
+1 -1
View File
@@ -129,7 +129,7 @@ html:not([data-theme="dark"]) .doc-footer {
z-index: var(--ifm-z-index-overlay);
}
.tabs-wrapper:not(.code-tabs) .tabs-container > div {
.tabs-wrapper:not(.code-tabs) > .tabs-container > div:not(.tablist-wrapper) {
padding-top: var(--ifm-base-margin-vertical);
}
+2
View File
@@ -83,11 +83,13 @@
--ifm-code-border-color: #E5E7EB;
--ifm-code-background: #F9FAFB;
--ifm-code-color: #4B5563;
--ifm-code-tabs-color: #6F6F6F;
--ifm-code-tabs-active-bg: transparent;
--ifm-code-tabs-active-color: #F4F4F4;
--ifm-code-action-hover-bg: rgba(141, 141, 141, 0.16);
--ifm-pre-padding: 16px;
--docusaurus-highlighted-code-line-bg: #393939;
--ifm-code-title-color: #737373;
/* Tooltip */
--ifm-tooltip-background-color: #fff;
+24 -9
View File
@@ -1,20 +1,23 @@
import React from 'react';
import clsx from 'clsx';
import {useThemeConfig, usePrismTheme} from '@docusaurus/theme-common';
import Highlight, {defaultProps} from 'prism-react-renderer';
import React, { useEffect } from 'react';
import {
containsLineNumbers,
parseCodeBlockTitle,
parseLanguage,
parseLines,
containsLineNumbers,
useCodeWordWrap,
} from '@docusaurus/theme-common/internal';
import Highlight, {defaultProps} from 'prism-react-renderer';
import Line from '@theme/CodeBlock/Line';
import {usePrismTheme, useThemeConfig} from '@docusaurus/theme-common';
import Container from '@theme/CodeBlock/Container';
import styles from './styles.module.css';
import CopyButton from '../../CopyButton';
import Line from '@theme/CodeBlock/Line';
import ThemedImage from '@theme/ThemedImage';
import Tooltip from '../../Tooltip';
import clsx from 'clsx';
import styles from './styles.module.css';
import useBaseUrl from '@docusaurus/useBaseUrl';
import useIsBrowser from '@docusaurus/useIsBrowser';
export default function CodeBlockString({
children,
@@ -23,14 +26,17 @@ export default function CodeBlockString({
title: titleProp,
showLineNumbers: showLineNumbersProp,
language: languageProp,
noReport = false
}) {
const {
prism: {defaultLanguage, magicComments},
reportCodeLinkPrefix
} = useThemeConfig();
const language =
languageProp ?? parseLanguage(blockClassName) ?? defaultLanguage;
const prismTheme = usePrismTheme();
const wordWrap = useCodeWordWrap();
const isBrowser = useIsBrowser();
// 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:
// "title=\"xyz\"" => title: "\"xyz\""
@@ -63,7 +69,7 @@ export default function CodeBlockString({
/* eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex */
tabIndex={0}
ref={wordWrap.codeBlockRef}
className={clsx(className, styles.codeBlock, 'thin-scrollbar')}>
className={clsx(className, styles.codeBlock, 'thin-scrollbar', tokens.length === 1 ? styles.thinCodeWrapper : '')}>
<code
className={clsx(
styles.codeBlockLines,
@@ -85,7 +91,16 @@ export default function CodeBlockString({
)}
</Highlight>
<div className={styles.buttonGroup}>
{/* <CopyButton className={styles.codeButton} code={code} /> */}
{!noReport && (
<Tooltip text="Report Incorrect Code">
<a href={`${reportCodeLinkPrefix}&title=${encodeURIComponent(`Docs(Code Issue): Code Issue in ${isBrowser ? location.pathname : ''}`)}`} target="_blank" className='report-code code-action img-url'>
<ThemedImage alt='Report Incorrect Code' sources={{
light: useBaseUrl('/img/alert-code.png'),
dark: useBaseUrl('/img/alert-code-dark.png')
}} className="no-zoom-img" />
</a>
</Tooltip>
)}
<CopyButton buttonClassName='code-action' text={code}>
<ThemedImage alt='Copy to Clipboard' sources={{
light: useBaseUrl('/img/clipboard-copy.png'),
@@ -58,11 +58,11 @@
display: flex;
column-gap: 0.2rem;
position: absolute;
right: calc(var(--ifm-pre-padding) / 4 - 2px);
top: calc(var(--ifm-pre-padding) / 4 - 2px);
right: var(--ifm-pre-padding);
top: var(--ifm-pre-padding);
}
.buttonGroup button {
.buttonGroup .code-action {
display: flex;
align-items: center;
background: var(--prism-background-color);
@@ -80,6 +80,10 @@
opacity: 1 !important;
}
.thinCodeWrapper + .buttonGroup {
top: calc(var(--ifm-pre-padding) / 4 - 2px) !important;
}
:global(.theme-code-block:hover) .buttonGroup button {
opacity: 0.4;
}
+7 -23
View File
@@ -1,13 +1,8 @@
import React, {isValidElement} from 'react';
import CopyButton from '../CopyButton';
import ElementContent from '@theme/CodeBlock/Content/Element';
import StringContent from '@theme/CodeBlock/Content/String';
import ThemedImage from '@theme/ThemedImage';
import Tooltip from '../Tooltip';
import useBaseUrl from '@docusaurus/useBaseUrl';
import useIsBrowser from '@docusaurus/useIsBrowser';
import {useThemeConfig} from '@docusaurus/theme-common';
/**
* Best attempt to make the children a plain string so it is copyable. If there
@@ -22,7 +17,7 @@ function maybeStringifyChildren(children) {
// The children is now guaranteed to be one/more plain strings
return Array.isArray(children) ? children.join('') : children;
}
export default function CodeBlock({children: rawChildren, noHeader = false, ...props}) {
export default function CodeBlock({children: rawChildren, noReport = false, ...props}) {
// The Prism theme on SSR is always the default theme but the site theme can
// be in a different mode. React hydration doesn't update DOM styles that come
// from SSR. Hence force a re-render after mounting to apply the current
@@ -31,29 +26,18 @@ export default function CodeBlock({children: rawChildren, noHeader = false, ...p
const children = maybeStringifyChildren(rawChildren);
const CodeBlockComp =
typeof children === 'string' ? StringContent : ElementContent;
const {reportCodeLinkPrefix} = useThemeConfig();
const title = props.title;
delete props.title;
return (
<div className='code-wrapper'>
{!noHeader && (
{title && (
<div className='code-header'>
<Tooltip text="Report Incorrect Code">
<a href={`${reportCodeLinkPrefix}&title=${encodeURIComponent(`Docs(Code Issue): Code Issue in ${isBrowser ? location.pathname : ''}`)}`} target="_blank" className='report-code code-action img-url'>
<ThemedImage alt='Report Incorrect Code' sources={{
light: useBaseUrl('/img/alert-code.png'),
dark: useBaseUrl('/img/alert-code-dark.png')
}} className="no-zoom-img" />
</a>
</Tooltip>
<CopyButton buttonClassName='code-action' text={children}>
<ThemedImage alt='Copy to Clipboard' sources={{
light: useBaseUrl('/img/clipboard-copy.png'),
dark: useBaseUrl('/img/clipboard-copy-dark.png')
}} className="no-zoom-img" />
</CopyButton>
{title}
</div>
)}
<CodeBlockComp key={String(isBrowser)} {...props} className={noHeader ? 'no-header-block' : ''}>
<CodeBlockComp key={String(isBrowser)} {...props} noReport={noReport} className={title ? '' : 'no-header-block'}>
{children}
</CodeBlockComp>
</div>
+45 -37
View File
@@ -1,12 +1,14 @@
import React, {useState, cloneElement, isValidElement, useEffect} from 'react';
import clsx from 'clsx';
import useIsBrowser from '@docusaurus/useIsBrowser';
import {duplicates} from '@docusaurus/theme-common';
import React, {cloneElement, isValidElement, useEffect, useState} from 'react';
import {
useScrollPositionBlocker,
useTabGroupChoice,
} from '@docusaurus/theme-common/internal';
import clsx from 'clsx';
import {duplicates} from '@docusaurus/theme-common';
import styles from './styles.module.css';
import useIsBrowser from '@docusaurus/useIsBrowser';
// A very rough duck type, but good enough to guard against mistakes while
// allowing customization
function isTabItem(comp) {
@@ -20,6 +22,8 @@ function TabsComponent(props) {
values: valuesProp,
groupId,
className,
isCodeTabs = false,
codeTitle
} = props;
const children = React.Children.map(props.children, (child) => {
if (isValidElement(child) && isTabItem(child)) {
@@ -113,39 +117,42 @@ function TabsComponent(props) {
};
return (
<div className={clsx('tabs-container', styles.tabList)}>
<ul
role="tablist"
aria-orientation="horizontal"
className={clsx(
'tabs',
{
'tabs--block': block,
},
className,
)}>
{values.map(({value, label, attributes}) => (
<li
role="tab"
tabIndex={selectedValue === value ? 0 : -1}
aria-selected={selectedValue === value}
key={value}
ref={(tabControl) => tabRefs.push(tabControl)}
onKeyDown={handleKeydown}
onFocus={handleTabChange}
onClick={handleTabChange}
{...attributes}
className={clsx(
'tabs__item',
styles.tabItem,
attributes?.className,
{
'tabs__item--active': selectedValue === value,
},
)}>
{label ?? value}
</li>
))}
</ul>
<div className={`tablist-wrapper ${isCodeTabs ? 'code-header' : ''}`}>
{isCodeTabs && <span className='code-title'>{codeTitle}</span>}
<ul
role="tablist"
aria-orientation="horizontal"
className={clsx(
'tabs',
{
'tabs--block': block,
},
className,
)}>
{values.map(({value, label, attributes}) => (
<li
role="tab"
tabIndex={selectedValue === value ? 0 : -1}
aria-selected={selectedValue === value}
key={value}
ref={(tabControl) => tabRefs.push(tabControl)}
onKeyDown={handleKeydown}
onFocus={handleTabChange}
onClick={handleTabChange}
{...attributes}
className={clsx(
'tabs__item',
styles.tabItem,
attributes?.className,
{
'tabs__item--active': selectedValue === value,
},
)}>
{label ?? value}
</li>
))}
</ul>
</div>
{lazy ? (
cloneElement(
@@ -183,6 +190,7 @@ export default function Tabs(props) {
// Remount tabs after hydration
// Temporary fix for https://github.com/facebook/docusaurus/issues/5653
key={String(isBrowser)}
isCodeTabs={props.wrapperClassName?.search('code-tabs') !== -1 || props.groupId === 'npm2yarn'}
{...props}
/>
</div>