Skip to content

Commit

Permalink
feat(share): allow disabling share capabilities (#50)
Browse files Browse the repository at this point in the history
  • Loading branch information
YossiSaadi authored Mar 26, 2024
1 parent dd824af commit f618f37
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 19 deletions.
3 changes: 2 additions & 1 deletion .storybook/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ const preview: Preview = {
introCode: {
jsx: `<VibeNext.Heading>Online Playground</VibeNext.Heading>`,
css: ""
}
},
share: true,
},
},
};
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ The addon configuration is done through Storybook's `preview`. Few of the parame
- `autocompletions`: Optional. An array of autocompletions that should be used on the playground. Default is an empty array. We recommend on using `react-docgen` to generate a documentation output and run our util function on the output. You can use whatever tool you'd like as long as it matches the expected format in the addon. _Default is no autocompletions._
- `editorTheme`: Optional. The theme that should be used on the playground. _Default is your Storybook theme._
- `initialCode`: Optional. The initial code ("welcome") that should be rendered on the playground. _Default is empty editor._
- `share`: Optional. A boolean that allow users to share the code. _Default is false._

On your `.storybook/preview.ts` file, you should add something similar to the following:

Expand Down
37 changes: 26 additions & 11 deletions src/components/Editor/EditorToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,18 @@ import {
} from "@/hooks";
import EditorToolbarButton from "./EditorToolbarButton";
import EditorToolbarDivider from "./EditorToolbarDivider";
import { useAddonState, useStorybookApi } from "@storybook/manager-api";
import { DEFAULT_ADDON_STATE, PANEL_ID } from "@/consts";
import { PlaygroundState } from "@/types";
import {
useAddonState,
useParameter,
useStorybookApi,
} from "@storybook/manager-api";
import {
ADDON_ID_FOR_PARAMETERS,
DEFAULT_ADDON_PARAMETERS,
DEFAULT_ADDON_STATE,
PANEL_ID,
} from "@/consts";
import { PlaygroundParameters, PlaygroundState } from "@/types";
import styles from "./EditorToolbar.module.css";

const EditorToolbar: React.FC = () => {
Expand All @@ -22,6 +31,10 @@ const EditorToolbar: React.FC = () => {
PANEL_ID,
DEFAULT_ADDON_STATE
);
const { share: enableShare } = useParameter<PlaygroundParameters>(
ADDON_ID_FOR_PARAMETERS,
DEFAULT_ADDON_PARAMETERS
);
const { code, selectedTab, fontSize } = state;

const selectPlaygroundStory = useCallback(() => {
Expand Down Expand Up @@ -63,14 +76,16 @@ const EditorToolbar: React.FC = () => {
disabled={isCopied || !shouldAllowCopy}
onClick={onCopy}
/>
<EditorToolbarButton
tooltip={shouldAllowShare ? "" : "Editor is empty"}
text={isShareCopied ? "Copied!" : "Share"}
icon={isShareCopied ? "check" : "share"}
color={isShareCopied ? "green" : undefined}
disabled={isShareCopied || !shouldAllowShare}
onClick={onShare}
/>
{enableShare && (
<EditorToolbarButton
tooltip={shouldAllowShare ? "" : "Editor is empty"}
text={isShareCopied ? "Copied!" : "Share"}
icon={isShareCopied ? "check" : "share"}
color={isShareCopied ? "green" : undefined}
disabled={isShareCopied || !shouldAllowShare}
onClick={onShare}
/>
)}
<EditorToolbarButton
text="Format"
icon="paintbrush"
Expand Down
1 change: 1 addition & 0 deletions src/consts/parameter-consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export const DEFAULT_ADDON_PARAMETERS: PlaygroundParameters = {
autocompletions: {},
editorTheme: null,
introCode: null,
share: false,
};
6 changes: 3 additions & 3 deletions src/hooks/useInitialCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const useInitialCode = () => {
DEFAULT_ADDON_STATE
);
const { hasInitialCodeLoaded } = state;
const { introCode } = useParameter<PlaygroundParameters>(
const { introCode, share: enableShare } = useParameter<PlaygroundParameters>(
ADDON_ID_FOR_PARAMETERS,
DEFAULT_ADDON_PARAMETERS
);
Expand All @@ -35,14 +35,14 @@ const useInitialCode = () => {
}, [getQueryParam]);

const initialCodeToSet = useMemo(() => {
if (hasValidCode(sharedCode)) {
if (enableShare && hasValidCode(sharedCode)) {
return sharedCode;
}
if (hasValidCode(introCode)) {
return introCode;
}
return DEFAULT_ADDON_STATE.code;
}, [sharedCode, introCode]);
}, [enableShare, sharedCode, introCode]);

useEffect(() => {
if (hasInitialCodeLoaded || introCode === null) {
Expand Down
17 changes: 13 additions & 4 deletions src/hooks/useShare.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import { useCallback, useMemo, useState } from "react";
import { Code } from "@/types";
import { Code, PlaygroundParameters } from "@/types";
import { compressAndEncode } from "@/utils";
import { SNIPPET_SHARE_QUERY_ID } from "@/consts";
import {
ADDON_ID_FOR_PARAMETERS,
DEFAULT_ADDON_PARAMETERS,
SNIPPET_SHARE_QUERY_ID,
} from "@/consts";
import usePlaygroundState from "./usePlaygroundState";
import { useParameter } from "@storybook/manager-api";

interface UseShareReturnType {
onShare: () => Promise<void>;
Expand All @@ -12,11 +17,15 @@ interface UseShareReturnType {

const useShare = (code: Code): UseShareReturnType => {
const { playgroundStoryBaseUrl } = usePlaygroundState();
const { share: enableShare } = useParameter<PlaygroundParameters>(
ADDON_ID_FOR_PARAMETERS,
DEFAULT_ADDON_PARAMETERS
);
const [isShareCopied, setShareCopied] = useState(false);

const shouldAllowShare = useMemo(
() => Boolean(code?.jsx || code?.css),
[code?.css, code?.jsx]
() => Boolean(code?.jsx || code?.css) && enableShare,
[code?.css, code?.jsx, enableShare]
);

const onShare = useCallback(async () => {
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export interface PlaygroundParameters {
autocompletions?: AutocompletionsMetadata;
editorTheme?: EditorTheme;
introCode?: Code;
share?: boolean;
}

type Components = Record<string, React.ComponentType | React.ExoticComponent>;
Expand Down

0 comments on commit f618f37

Please sign in to comment.