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

[BD-46] docs: add copy URL and reset buttons to playground page #2323

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions www/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"gatsby-plugin-segment-js": "^3.7.1",
"gatsby-source-filesystem": "^4.17.0",
"gatsby-transformer-react-docgen": "^7.17.0",
"localforage": "^1.10.0",
"lodash.debounce": "^4.0.8",
"prism-react-renderer": "^1.3.3",
"prop-types": "^15.8.1",
Expand Down
2 changes: 2 additions & 0 deletions www/playroom.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const path = require('path');
const { storageKey } = require('./playroom/constants');

module.exports = {
baseUrl: '/playroom/',
Expand Down Expand Up @@ -57,4 +58,5 @@ module.exports = {
},
}),
iframeSandbox: 'allow-scripts allow-same-origin',
storageKey,
};
3 changes: 3 additions & 0 deletions www/playroom/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
storageKey: 'playroom__paragon',
};
6 changes: 6 additions & 0 deletions www/src/components/header/Header.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
.pgn-doc__header {
z-index: $zindex-header;

.pgn-doc__playground-title {
position: absolute;
left: 50%;
transform: translate(-50%, 0);
}

.pgn-doc__header-title {
display: flex;
align-items: center;
Expand Down
12 changes: 9 additions & 3 deletions www/src/components/header/SiteTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { Link } from 'gatsby';
// @ts-ignore
import Logo from '../../images/diamond.svg';

interface SiteTitleProps {
title: string,
isFullVersion: boolean,
className?: string,
}

export default function SiteTitle({ title, isFullVersion } : SiteTitleProps) {
export default function SiteTitle({ title, isFullVersion, className } : SiteTitleProps) {
return (
<Link
to="/"
style={{ textDecoration: 'none' }}
className="d-block"
className={classNames('d-block text-decoration-none', className)}
>
<div className="pgn-doc__header-title">
<span
Expand All @@ -40,4 +41,9 @@ export default function SiteTitle({ title, isFullVersion } : SiteTitleProps) {
SiteTitle.propTypes = {
title: PropTypes.string.isRequired,
isFullVersion: PropTypes.bool.isRequired,
className: PropTypes.string,
};

SiteTitle.defaultProps = {
className: undefined,
};
56 changes: 51 additions & 5 deletions www/src/pages/playground.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import React, { useEffect, useRef, useState } from 'react';
import { Hyperlink } from '~paragon-react';
import {
Hyperlink,
StatefulButton,
Button,
Icon,
} from '~paragon-react';
import { ContentCopy, Check } from '~paragon-icons';
import PropTypes from 'prop-types';
import { navigate } from 'gatsby';
import localforage from 'localforage';

import SEO from '../components/SEO';
import { SiteTitle } from '../components/header';
import { storageKey } from '../../playroom/constants';

const FEEDBACK_URL = 'https://github.com/openedx/paragon/issues/new?assignees=&labels=playground&template=feedback_template.md&title=[Playground]';

const playroomStorage = localforage.createInstance({ name: storageKey });

export default function Playground({ location }) {
const iframeRef = useRef<HTMLIFrameElement>(null);
const [initialSearchParams, setInitialSearchParams] = useState('');
const searchValue = useRef(location.search || '');
const [copyUrlState, setCopyUrlState] = useState('default');

useEffect(() => {
setInitialSearchParams(location.search);
Expand All @@ -35,20 +46,54 @@ export default function Playground({ location }) {
return () => clearInterval(iframeUrlPoll);
}, []);

useEffect(() => {
setCopyUrlState('default');
}, [location.href]);

return (
<div className="d-flex flex-column w-100 vh-100 m-0 p-0">
<SEO title="Playground" />
<div className="pgn-doc__header py-3 bg-dark text-white sticky-top">
<div className="d-flex align-items-center justify-content-center">
<div className="d-flex align-items-center justify-content-end px-4" style={{ gap: '16px' }}>
viktorrusakov marked this conversation as resolved.
Show resolved Hide resolved
<Button
variant="inverse-tertiary"
onClick={() => {
playroomStorage.clear().then(() => {
iframeRef!.current!.contentWindow!.location.search = '?code=N4XyA';
viktorrusakov marked this conversation as resolved.
Show resolved Hide resolved
});
}}
>
Reset
</Button>
<StatefulButton
variant="inverse-tertiary"
state={copyUrlState}
onClick={() => {
setCopyUrlState('copied');
navigator.clipboard.writeText(location.href);
global.analytics.track('openedx.paragon.docs.playground.url-copied');
}}
labels={{
default: 'Copy URL',
copied: 'Copied',
}}
icons={{
default: <Icon src={ContentCopy} />,
copied: <Icon src={Check} />,
}}
/>
<Hyperlink
destination={FEEDBACK_URL}
target="_blank"
className="text-white position-absolute"
style={{ left: '16px' }}
className="text-white"
>
Leave feedback
</Hyperlink>
<SiteTitle title="Paragon Design System" isFullVersion />
<SiteTitle
title="Paragon Design System"
isFullVersion
className="pgn-doc__playground-title"
/>
</div>
</div>
<iframe
Expand All @@ -71,5 +116,6 @@ export default function Playground({ location }) {
Playground.propTypes = {
location: PropTypes.shape({
search: PropTypes.string,
href: PropTypes.string,
}).isRequired,
};