Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOP-4615: (Feature) New Structured Data #1274

Merged
merged 9 commits into from
Oct 8, 2024
2 changes: 2 additions & 0 deletions plugins/gatsby-source-snooty-prod/gatsby-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ exports.sourceNodes = async ({ actions, createContentDigest, createNodeId, getNo
id: key,
page_id: key,
ast: doc.ast,
facets: doc.facets,
internal: {
type: 'Page',
contentDigest: createContentDigest(doc),
Expand Down Expand Up @@ -379,6 +380,7 @@ exports.createSchemaCustomization = ({ actions }) => {
branch: String
pagePath: String
ast: JSON!
facets: [JSON]
metadata: SnootyMetadata @link
componentNames: [String!]
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/Breadcrumbs/BreadcrumbContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const crumbObjectShape = {
};

BreadcrumbContainer.propTypes = {
breadcrumbs: PropTypes.shape(crumbObjectShape).isRequired,
breadcrumbs: PropTypes.arrayOf(PropTypes.shape(crumbObjectShape)).isRequired,
};

export default BreadcrumbContainer;
144 changes: 81 additions & 63 deletions src/components/Code/Code.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { css } from '@emotion/react';
import React, { useCallback, useContext } from 'react';
import React, { useCallback, useContext, useMemo } from 'react';
import PropTypes from 'prop-types';
import styled from '@emotion/styled';
import { default as CodeBlock } from '@leafygreen-ui/code';
Expand All @@ -12,6 +12,8 @@ import { TabContext } from '../Tabs/tab-context';
import { reportAnalytics } from '../../utils/report-analytics';
import { getLanguage } from '../../utils/get-language';
import { DRIVER_ICON_MAP } from '../icons/DriverIconMap';
import { SoftwareSourceCodeSd } from '../../utils/structured-data';
import { usePageContext } from '../../context/page-context';
import { baseCodeStyle, borderCodeStyle, lgStyles } from './styles/codeStyle';
import { CodeContext } from './code-context';

Expand Down Expand Up @@ -41,6 +43,7 @@ const Code = ({
const { setActiveTab } = useContext(TabContext);
const { languageOptions, codeBlockLanguage } = useContext(CodeContext);
const { darkMode } = useDarkMode();
const { slug } = usePageContext();
const code = value;
let language = (languageOptions?.length > 0 && codeBlockLanguage) || getLanguage(lang);

Expand Down Expand Up @@ -85,77 +88,92 @@ const Code = ({
reportAnalytics('CodeblockCopied', { code });
}, [code]);

const softwareSourceCodeSd = useMemo(() => {
const sd = new SoftwareSourceCodeSd({ code, lang, slug });
return sd.isValid() ? sd.toString() : undefined;
}, [code, lang, slug]);

return (
<div
css={css`
${baseCodeStyle}

// Remove whitespace when copyable false
> div > div {
display: grid;
grid-template-columns: ${!copyable && (languageOptions?.length === 0 || language === 'none')
? 'auto 0px !important'
: 'code panel'};
}

> div {
border-top-left-radius: ${captionBorderRadius};
border-top-right-radius: ${captionBorderRadius};
display: grid;
border-color: ${palette.gray.light2};

.dark-theme & {
border-color: ${palette.gray.dark2};
<>
{softwareSourceCodeSd && (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: softwareSourceCodeSd,
}}
/>
)}
<div
css={css`
${baseCodeStyle}

// Remove whitespace when copyable false
> div > div {
display: grid;
grid-template-columns: ${!copyable && (languageOptions?.length === 0 || language === 'none')
? 'auto 0px !important'
: 'code panel'};
}
}

pre {
background-color: ${palette.gray.light3};
color: ${palette.black};
> div {
border-top-left-radius: ${captionBorderRadius};
border-top-right-radius: ${captionBorderRadius};
display: grid;
border-color: ${palette.gray.light2};

.dark-theme & {
background-color: ${palette.black};
color: ${palette.gray.light3};
.dark-theme & {
border-color: ${palette.gray.dark2};
}
}
}

[data-testid='leafygreen-code-panel'] {
background-color: ${palette.white};
border-color: ${palette.gray.light2};
pre {
background-color: ${palette.gray.light3};
color: ${palette.black};

.dark-theme & {
background-color: ${palette.gray.dark2};
border-color: ${palette.gray.dark2};
.dark-theme & {
background-color: ${palette.black};
color: ${palette.gray.light3};
}
}
}

${lgStyles}
`}
>
{captionSpecified && (
<div>
<CaptionContainer style={{ '--border-color': darkMode ? palette.gray.dark2 : palette.gray.light2 }}>
<Caption style={{ '--color': darkMode ? palette.gray.light2 : palette.gray.dark1 }}>{caption}</Caption>
</CaptionContainer>
</div>
)}
<CodeBlock
copyable={copyable}
highlightLines={emphasizeLines}
language={language}
languageOptions={languageOptions}
onChange={(selectedOption) => {
setActiveTab({ drivers: selectedOption.id });
}}
onCopy={reportCodeCopied}
showLineNumbers={linenos}
showCustomActionButtons={sourceSpecified}
customActionButtons={customActionButtonList}
lineNumberStart={lineno_start}

[data-testid='leafygreen-code-panel'] {
background-color: ${palette.white};
border-color: ${palette.gray.light2};

.dark-theme & {
background-color: ${palette.gray.dark2};
border-color: ${palette.gray.dark2};
}
}

${lgStyles}
`}
>
{code}
</CodeBlock>
</div>
{captionSpecified && (
<div>
<CaptionContainer style={{ '--border-color': darkMode ? palette.gray.dark2 : palette.gray.light2 }}>
<Caption style={{ '--color': darkMode ? palette.gray.light2 : palette.gray.dark1 }}>{caption}</Caption>
</CaptionContainer>
</div>
)}
<CodeBlock
copyable={copyable}
highlightLines={emphasizeLines}
language={language}
languageOptions={languageOptions}
onChange={(selectedOption) => {
setActiveTab({ drivers: selectedOption.id });
}}
onCopy={reportCodeCopied}
showLineNumbers={linenos}
showCustomActionButtons={sourceSpecified}
customActionButtons={customActionButtonList}
lineNumberStart={lineno_start}
>
{code}
</CodeBlock>
</div>
</>
);
};

Expand Down
16 changes: 9 additions & 7 deletions src/components/Code/CodeIO.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ const outputButtonStyling = LeafyCss`
margin: 8px;
`;

const outputContainerStyle = (showOutput) => LeafyCss`
${!showOutput && 'display: none;'}
`;

const CodeIO = ({ nodeData: { children }, ...rest }) => {
const { darkMode } = useDarkMode();
const needsIOToggle = children.length === 2;
Expand All @@ -32,12 +36,8 @@ const CodeIO = ({ nodeData: { children }, ...rest }) => {
const outputBorderRadius = !showOutput ? '12px' : '0px';
const singleInputBorderRadius = onlyInputSpecified ? '12px' : '0px';

const handleClick = (e) => {
if (showOutput) {
setShowOutput(false);
} else {
setShowOutput(true);
}
const handleClick = () => {
setShowOutput((val) => !val);
};

if (children.length === 0) {
Expand Down Expand Up @@ -77,7 +77,9 @@ const CodeIO = ({ nodeData: { children }, ...rest }) => {
{buttonText}
</Button>
</IOToggle>
{showOutput && <Output nodeData={children[1]} />}
<div className={outputContainerStyle(showOutput)}>
<Output nodeData={children[1]} />
</div>
</>
)}
{onlyInputSpecified && <Input nodeData={children[0]} />}
Expand Down
67 changes: 42 additions & 25 deletions src/components/Code/Output.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import React from 'react';
import React, { useMemo } from 'react';
import styled from '@emotion/styled';
import PropTypes from 'prop-types';
import { default as CodeBlock } from '@leafygreen-ui/code';
import { useDarkMode } from '@leafygreen-ui/leafygreen-provider';
import { palette } from '@leafygreen-ui/palette';
import { getLanguage } from '../../utils/get-language';
import { SoftwareSourceCodeSd } from '../../utils/structured-data';
import { usePageContext } from '../../context/page-context';

const OutputContainer = styled.div`
> div > * {
Expand All @@ -27,36 +29,51 @@ const OutputContainer = styled.div`
}
`;

const Output = ({ nodeData: { children }, ...rest }) => {
const Output = ({ nodeData: { children } }) => {
const { darkMode } = useDarkMode();
const { emphasize_lines, value, linenos, lang, lineno_start } = children[0];
const language = getLanguage(lang);
const { slug } = usePageContext();
const softwareSourceCodeSd = useMemo(() => {
const sd = new SoftwareSourceCodeSd({ code: value, lang, slug });
return sd.isValid() ? sd.toString() : undefined;
}, [value, lang, slug]);

return (
<OutputContainer
style={
darkMode
? {
'--code-container-border': 'none',
'--code-pre-border': `1px solid ${palette.gray.dark2}`,
}
: {
'--code-container-border': 'initial',
'--code-pre-border': `none`,
}
}
>
<CodeBlock
highlightLines={emphasize_lines}
language={language}
showLineNumbers={linenos}
darkMode={true}
copyable={false}
lineNumberStart={lineno_start}
<>
{softwareSourceCodeSd && (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: softwareSourceCodeSd,
}}
/>
)}
<OutputContainer
style={
darkMode
? {
'--code-container-border': 'none',
'--code-pre-border': `1px solid ${palette.gray.dark2}`,
}
: {
'--code-container-border': 'initial',
'--code-pre-border': `none`,
}
}
>
{value}
</CodeBlock>
</OutputContainer>
<CodeBlock
highlightLines={emphasize_lines}
language={language}
showLineNumbers={linenos}
darkMode={true}
copyable={false}
lineNumberStart={lineno_start}
>
{value}
</CodeBlock>
</OutputContainer>
</>
);
};

Expand Down
37 changes: 20 additions & 17 deletions src/components/Collapsible/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Icon from '@leafygreen-ui/icon';
import IconButton from '@leafygreen-ui/icon-button';
import { cx } from '@leafygreen-ui/emotion';
import { Body } from '@leafygreen-ui/typography';
import { HeadingContextProvider } from '../../context/heading-context';
import { findAllNestedAttribute } from '../../utils/find-all-nested-attribute';
import { isBrowser } from '../../utils/is-browser';
import { reportAnalytics } from '../../utils/report-analytics';
Expand Down Expand Up @@ -65,25 +66,27 @@ const Collapsible = ({ nodeData: { children, options }, sectionDepth, ...rest })
}, [childrenHashIds, hash, open]);

return (
<Box className={cx('collapsible', collapsibleStyle)}>
<Box className={cx(headerContainerStyle)}>
<Box>
{/* Adding 1 to reflect logic in parser, but want to show up as H2 for SEO reasons */}
<Heading className={cx(headerStyle)} sectionDepth={sectionDepth + 1} as={2} nodeData={headingNodeData}>
{heading}
</Heading>
<Body baseFontSize={13}>{subHeading}</Body>
<HeadingContextProvider ignoreNextHeading={true} heading={heading}>
<Box className={cx('collapsible', collapsibleStyle)}>
<Box className={cx(headerContainerStyle)}>
<Box>
{/* Adding 1 to reflect logic in parser, but want to show up as H2 for SEO reasons */}
<Heading className={cx(headerStyle)} sectionDepth={sectionDepth + 1} as={2} nodeData={headingNodeData}>
{heading}
</Heading>
<Body baseFontSize={13}>{subHeading}</Body>
</Box>
<IconButton className={iconStyle} aria-labelledby={'Expand the collapsed content'} onClick={onIconClick}>
<Icon glyph={open ? 'ChevronDown' : 'ChevronRight'} />
</IconButton>
</Box>
<Box className={cx(innerContentStyle(open))}>
{children.map((c, i) => (
<ComponentFactory nodeData={c} key={i} sectionDepth={sectionDepth} {...rest}></ComponentFactory>
))}
</Box>
<IconButton className={iconStyle} aria-labelledby={'Expand the collapsed content'} onClick={onIconClick}>
<Icon glyph={open ? 'ChevronDown' : 'ChevronRight'} />
</IconButton>
</Box>
<Box className={cx(innerContentStyle(open))}>
{children.map((c, i) => (
<ComponentFactory nodeData={c} key={i} sectionDepth={sectionDepth} {...rest}></ComponentFactory>
))}
</Box>
</Box>
</HeadingContextProvider>
);
};

Expand Down
Loading
Loading