Merge pull request #897 from quantified-uncertainty/copy-share-link

"Copy share link" button
This commit is contained in:
Ozzie Gooen 2022-07-28 12:18:10 -07:00 committed by GitHub
commit f7e6061f17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 74 additions and 7 deletions

View File

@ -13,6 +13,7 @@ import { yupResolver } from "@hookform/resolvers/yup";
import { import {
ChartSquareBarIcon, ChartSquareBarIcon,
CheckCircleIcon, CheckCircleIcon,
ClipboardCopyIcon,
CodeIcon, CodeIcon,
CogIcon, CogIcon,
CurrencyDollarIcon, CurrencyDollarIcon,
@ -40,6 +41,7 @@ import {
defaultColor, defaultColor,
defaultTickFormat, defaultTickFormat,
} from "../lib/distributionSpecBuilder"; } from "../lib/distributionSpecBuilder";
import { Button } from "./ui/Button";
type PlaygroundProps = SquiggleChartProps & { type PlaygroundProps = SquiggleChartProps & {
/** The initial squiggle string to put in the playground */ /** The initial squiggle string to put in the playground */
@ -49,6 +51,8 @@ type PlaygroundProps = SquiggleChartProps & {
onSettingsChange?(settings: any): void; onSettingsChange?(settings: any): void;
/** Should we show the editor? */ /** Should we show the editor? */
showEditor?: boolean; showEditor?: boolean;
/** Useful for playground on squiggle website, where we update the anchor link based on current code and settings */
showShareButton?: boolean;
}; };
const schema = yup const schema = yup
@ -197,6 +201,29 @@ const RunControls: React.FC<{
); );
}; };
const ShareButton: React.FC = () => {
const [isCopied, setIsCopied] = useState(false);
const copy = () => {
navigator.clipboard.writeText((window.top || window).location.href);
setIsCopied(true);
setTimeout(() => setIsCopied(false), 1000);
};
return (
<div className="w-36">
<Button onClick={copy} wide>
{isCopied ? (
"Copied to clipboard!"
) : (
<div className="flex items-center space-x-1">
<ClipboardCopyIcon className="w-4 h-4" />
<span>Copy share link</span>
</div>
)}
</Button>
</div>
);
};
type PlaygroundContextShape = { type PlaygroundContextShape = {
getLeftPanelElement: () => HTMLDivElement | undefined; getLeftPanelElement: () => HTMLDivElement | undefined;
}; };
@ -220,6 +247,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
onCodeChange, onCodeChange,
onSettingsChange, onSettingsChange,
showEditor = true, showEditor = true,
showShareButton = false,
}) => { }) => {
const [code, setCode] = useMaybeControlledValue({ const [code, setCode] = useMaybeControlledValue({
value: controlledCode, value: controlledCode,
@ -370,6 +398,7 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
<StyledTab name="View Settings" icon={ChartSquareBarIcon} /> <StyledTab name="View Settings" icon={ChartSquareBarIcon} />
<StyledTab name="Input Variables" icon={CurrencyDollarIcon} /> <StyledTab name="Input Variables" icon={CurrencyDollarIcon} />
</StyledTab.List> </StyledTab.List>
<div className="flex space-x-2 items-center">
<RunControls <RunControls
autorunMode={autorunMode} autorunMode={autorunMode}
isStale={renderedCode !== code} isStale={renderedCode !== code}
@ -377,6 +406,8 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
isRunning={isRunning} isRunning={isRunning}
onAutorunModeChange={setAutorunMode} onAutorunModeChange={setAutorunMode}
/> />
{showShareButton && <ShareButton />}
</div>
</div> </div>
{vars.showEditor ? withEditor : withoutEditor} {vars.showEditor ? withEditor : withoutEditor}
</div> </div>

View File

@ -0,0 +1,22 @@
import clsx from "clsx";
import React from "react";
type Props = {
onClick: () => void;
children: React.ReactNode;
wide?: boolean; // stretch the button horizontally
};
export const Button: React.FC<Props> = ({ onClick, wide, children }) => {
return (
<button
className={clsx(
"rounded-md py-1.5 px-2 bg-slate-500 text-white text-xs font-semibold flex items-center justify-center space-x-1",
wide && "w-full"
)}
onClick={onClick}
>
{children}
</button>
);
};

View File

@ -21,3 +21,16 @@ including sampling settings, in squiggle.
{Template.bind({})} {Template.bind({})}
</Story> </Story>
</Canvas> </Canvas>
<Canvas>
<Story
name="With share button"
args={{
defaultCode: "normal(5,2)",
height: 800,
showShareButton: true,
}}
>
{Template.bind({})}
</Story>
</Canvas>

View File

@ -44,6 +44,7 @@ export default function PlaygroundPage() {
const playgroundProps = { const playgroundProps = {
defaultCode: "normal(0,1)", defaultCode: "normal(0,1)",
height: 700, height: 700,
showShareButton: true,
...hashData, ...hashData,
onCodeChange: (code) => setHashData({ initialSquiggleString: code }), onCodeChange: (code) => setHashData({ initialSquiggleString: code }),
onSettingsChange: (settings) => { onSettingsChange: (settings) => {