Skip to content

Commit

Permalink
feat: introduce import fallback option (#11)
Browse files Browse the repository at this point in the history
* feat: introduce import fallback option

* fix: Update build and run commands  to use pnpm instead of npm and remove unnecessary console.log and return statement

* feat: Add support for Component Story Format (CSF), add JSX component and add Meta and Source components

* fix: Update package.json version to 0.1.3

* style: Change @optional to @required

* fix: Remove unused import of Theme from @radix-ui/themes
  • Loading branch information
danilowoz committed Mar 27, 2024
1 parent 3d0d448 commit 51d7f62
Show file tree
Hide file tree
Showing 27 changed files with 230 additions and 628 deletions.
28 changes: 16 additions & 12 deletions .codesandbox/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,64 @@
"setupTasks": [
{
"name": "Install Dependencies",
"command": "npm install"
"command": "pnpm install"
}
],

// These tasks can be run from CodeSandbox. Running one will open a log in the app.
"tasks": {
"start": {
"name": "start",
"command": "pnpm run start"
},
"postinstall": {
"name": "postinstall",
"command": "npm run postinstall"
"command": "pnpm run postinstall"
},
"clean": {
"name": "clean",
"command": "npm run clean"
"command": "pnpm run clean"
},
"prebuild": {
"name": "prebuild",
"command": "npm run prebuild"
"command": "pnpm run prebuild"
},
"build": {
"name": "build",
"command": "npm run build",
"command": "pnpm run build",
"runAtStart": true
},
"build:watch": {
"name": "build:watch",
"command": "npm run build:watch"
"command": "pnpm run build:watch"
},
"test": {
"name": "test",
"command": "npm run test"
"command": "pnpm run test"
},
"prerelease": {
"name": "prerelease",
"command": "npm run prerelease"
"command": "pnpm run prerelease"
},
"release": {
"name": "release",
"command": "npm run release"
"command": "pnpm run release"
},
"eject-ts": {
"name": "eject-ts",
"command": "npm run eject-ts"
"command": "pnpm run eject-ts"
},
"storybook": {
"name": "storybook",
"command": "npm run storybook",
"command": "pnpm run storybook",
"runAtStart": true,
"preview": {
"port": 6006
}
},
"build-storybook": {
"name": "build-storybook",
"command": "npm run build-storybook"
"command": "pnpm run build-storybook"
}
}
}
17 changes: 2 additions & 15 deletions .storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,14 @@ import { Theme } from "@radix-ui/themes";
const preview: Preview = {
parameters: {
codesandbox: {
/**
* @required
* Workspace API key from codesandbox.io/t/permissions.
* This sandbox is created inside the given workspace
* and can be shared with team members.
*/
apiToken: import.meta.env.VITE_CSB_API_KEY,

/**
* List of dependencies to install in the sandbox
* @optional
*/
fallbackImport: "@radix-ui/themes",

dependencies: {
"@radix-ui/themes": "latest",
},

/**
* All required providers to run the sandbox properly, such as
* themes, i18n, store, and so on.
* @optional
*/
provider: `import { Theme } from "@radix-ui/themes";
import '@radix-ui/themes/styles.css';
Expand Down
6 changes: 4 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ The file outlines the structure of the addon's codebase:

In order to test the addon, you should run two commands:

1. `npm run build`: to build the CodeSandbox addon (re-run on every change);
2. `npm run storybook`: to open the Storybook instance with the new addon (reload every change);
1. `pnpm run build`: to build the CodeSandbox addon (re-run on every change);
2. `pnpm run storybook`: to open the Storybook instance with the new addon (reload every change);

Or, just use `pnpm run start`

## Deployment

Expand Down
16 changes: 13 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ To run the addon, you'll need to configure it in your Storybook's `.storybook/pr
```js
// .storybook/preview.js

import { Theme } from "@radix-ui/themes";

const preview: Preview = {
parameters: {
codesandbox: {
Expand All @@ -49,7 +47,7 @@ const preview: Preview = {
apiToken: process.env.VITE_CODESANDBOX_KEY, // For Vite use `import.meta.env.VITE_CODESANDBOX_KEY`

/**
* @optional
* @required
* Dependencies list to be installed in the sandbox.
*
* @note You cannot use local modules or packages since
Expand All @@ -64,6 +62,16 @@ const preview: Preview = {
"@myscope/mypackage": "1.0.0",
},

/**
* @required
* CodeSandbox will try to import all components by default from
* the given package, in case `mapComponent` property is not provided.
*
* This property is useful when your components imports are predictable
* and come from a single package and entry point.
*/
fallbackImport: "@radix-ui/themes",

/**
* @optional
* All required providers to run the sandbox properly,
Expand Down Expand Up @@ -143,6 +151,8 @@ const meta: Meta<typeof Button> = {

Make sure to provide the necessary values for [`apiToken`](https://codesandbox.io/t/permissions) and any additional dependencies or providers required for your specific setup.

For now, this addon only support [Component Story Format (CSF)](Component Story Format (CSF)) stories format.

## Additional Notes
- Ensure that you have proper permissions and access rights to the CodeSandbox workspace specified in the configuration.
- Verify the correctness of the dependencies and providers listed in the configuration to ensure the sandbox runs smoothly.
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@codesandbox/storybook-addon",
"version": "0.1.2",
"version": "0.1.3",
"description": "CSB",
"keywords": [
"storybook-addons"
Expand Down Expand Up @@ -29,6 +29,7 @@
"*.d.ts"
],
"scripts": {
"start": "pnpm run build && pnpm run storybook",
"clean": "rimraf ./dist",
"prebuild": "npm run clean",
"build": "tsup",
Expand Down Expand Up @@ -96,6 +97,7 @@
"dependencies": {
"@storybook/addon-docs": "^7.6.17",
"@storybook/addon-storysource": "^7.6.17",
"@storybook/docs-tools": "^7.6.17",
"@storybook/icons": "^1.2.9",
"prettier": "^3.2.5"
}
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

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

47 changes: 32 additions & 15 deletions src/Tool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { IconButton } from "@storybook/components";
import prettier from "prettier/standalone";
import prettierPluginBabel from "prettier/plugins/babel";
import prettierPluginEstree from "prettier/plugins/estree";
import { SNIPPET_RENDERED } from "@storybook/docs-tools";

import { TOOL_ID } from "./constants";
import { parseFileTree, parseImports } from "./utils";

const SNIPPET_RENDERED = `storybook/docs/snippet-rendered`;

type CSBParameters =
export type CSBParameters =
| {
apiToken: string;
fallbackImport?: string;
mapComponent?: Record<string, string[] | string | true>;
dependencies?: Record<string, string>;
provider?: string;
Expand Down Expand Up @@ -47,28 +48,44 @@ export const CodeSandboxTool = memo(function MyAddonSelector({
provider:
codesandboxParameters?.provider ??
`export default GenericProvider = ({ children }) => {
return children
return children
}`,
};

async function createSandbox() {
try {
setLoading(true);

/**
* Parse story imports
*/
let imports = ``;
for (const [key, value] of Object.entries(options.mapComponent)) {
if (Array.isArray(value)) {
imports += `import { ${value.join(", ")} } from '${key}';\n`;
} else if (value === true) {
imports += `import '${key}';\n`;
} else if (typeof value === "string") {
imports += `import ${value} from '${key}';\n`;
const { fallbackImport } = codesandboxParameters;
const importsMap = options.mapComponent;

// If fallbackImport is provided, add it to importsMap
if (fallbackImport) {
const componentNames = parseFileTree(storySource);

// Check if fallbackImport is already in importsMap
if (importsMap[fallbackImport]) {
const currentFallbackImport = importsMap[fallbackImport];

// Merge them
if (Array.isArray(currentFallbackImport)) {
importsMap[fallbackImport] = [
...new Set([...componentNames, ...currentFallbackImport]),
];
} else {
// Invalid use case
throw new Error(
"Invalid fallback import usage. The `import` used inside `mapComponent` and also used as `fallbackImport` must be an array.",
);
}
} else {
// Just added (0-config case)
importsMap[fallbackImport] = componentNames;
}
}

const imports = parseImports(importsMap);

/**
* File: combine & prettify them
*/
Expand Down
48 changes: 0 additions & 48 deletions src/stories/Button.tsx

This file was deleted.

24 changes: 0 additions & 24 deletions src/stories/Header.stories.ts

This file was deleted.

Loading

0 comments on commit 51d7f62

Please sign in to comment.