├── .github ├── FUNDING.yml └── workflows │ └── nodejs.yml ├── .gitignore ├── .nvmrc ├── LICENSE ├── README.md ├── assets └── logo.svg ├── package.json ├── packages ├── mock-addon-docs │ ├── .eslintignore │ ├── .eslintrc │ ├── .prettierrc │ ├── .storybook │ │ ├── main.js │ │ └── preview.jsx │ ├── package.json │ └── stories │ │ ├── assets │ │ └── logo.svg │ │ ├── docs │ │ ├── advanced-setup.mdx │ │ ├── footer │ │ │ └── index.jsx │ │ ├── installation-setup.mdx │ │ ├── introduction.mdx │ │ └── user-guide.mdx │ │ ├── examples │ │ ├── components │ │ │ ├── container │ │ │ │ ├── index.jsx │ │ │ │ └── styles.js │ │ │ ├── get-component │ │ │ │ ├── index.jsx │ │ │ │ └── styles.js │ │ │ └── response │ │ │ │ ├── index.jsx │ │ │ │ └── styles.js │ │ ├── stories │ │ │ ├── axios │ │ │ │ └── stories.jsx │ │ │ ├── fetch │ │ │ │ └── stories.jsx │ │ │ └── superagent │ │ │ │ └── stories.jsx │ │ └── utils │ │ │ ├── code-blocks.js │ │ │ └── index.js │ │ └── mock.js └── mock-addon │ ├── .babelrc.js │ ├── .eslintignore │ ├── .eslintrc │ ├── .github │ └── workflows │ │ └── release.yml │ ├── .gitignore │ ├── .prettierignore │ ├── .prettierrc │ ├── README.md │ ├── package.json │ ├── preset.js │ ├── scripts │ └── prepublish-checks.mjs │ └── src │ ├── Panel.js │ ├── components │ ├── ButtonToggle │ │ └── index.js │ ├── Card │ │ └── index.js │ ├── ErrorItem │ │ └── index.js │ └── MockItem │ │ └── index.js │ ├── index.js │ ├── preset │ ├── manager.js │ └── preview.js │ ├── typings.d.ts │ ├── utils │ ├── array.js │ ├── array.test.js │ ├── constants.js │ ├── faker.js │ ├── faker.test.js │ ├── headers.js │ ├── request.js │ ├── request.test.js │ ├── response.js │ ├── response.test.js │ ├── statusMap.js │ ├── url.js │ ├── url.test.js │ ├── validator.js │ └── validator.test.js │ └── withRoundTrip.js └── yarn.lock /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: nutboltu 4 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: ubuntu-latest 9 | 10 | strategy: 11 | matrix: 12 | node-version: [18.x, 20.x] 13 | 14 | steps: 15 | - uses: actions/checkout@v1 16 | - name: Use Node.js ${{ matrix.node-version }} 17 | uses: actions/setup-node@v4 18 | with: 19 | node-version: ${{ matrix.node-version }} 20 | - name: yarn install, build, and test 21 | run: | 22 | npm install -g yarn 23 | yarn 24 | yarn run ci 25 | env: 26 | CI: true 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE files 2 | .idea 3 | .vscode 4 | 5 | # dependencies 6 | node_modules 7 | **/node_modules 8 | 9 | #error files 10 | yarn-error.log 11 | 12 | #build files 13 | dist 14 | 15 | #lock files 16 | package-lock.json 17 | 18 | # OS Files 19 | .DS_Store 20 | 21 | # ignore static storybook 22 | 23 | **/storybook-static -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | lts/hydrogen -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2021 Farhad Yasir 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | Storybook addon mock 3 |

Storybook Addon Mock

4 |
5 | 6 |

7 | 8 | Actions Status 9 | 10 | 11 | Npm download 12 | 13 | 14 | npm version 15 | 16 | 17 | License 18 | 19 |

20 | 21 | [![NPM](https://nodei.co/npm/storybook-addon-mock.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/storybook-addon-mock/) 22 | 23 | 24 | This addon allows you to mock fetch or XMLHttprequest requests in [storybook](https://storybook.js.org/). 25 | If your component depends on backend requests, and your backend requests are not ready yet to feed your component, 26 | this addon provides mock response to build your component. 27 | 28 | 29 | ### Purpose 30 | 31 | There are few packages those help the developers to mock the backend requests while building components. 32 | But those packages aren't integrated properly in storybook and also there's no scope to play with those requests in the storybook. 33 | Mostly, there's no playground to modify the response and see the changes in the storybook. 34 | 35 | ### Highlights 36 | 37 | `storybook-addon-mock` provides the following features. 38 | 39 | 47 | 48 | ### Documentation 49 | 50 | [See the documentation](https://storybook-addon-mock.netlify.app) 51 | 52 | [Older(2.*) version documentation](https://github.com/nutboltu/storybook-addon-mock/blob/2.4.1/README.md) 53 | ### License 54 | 55 | This project is licensed under the MIT License - see the LICENSE file in the source code for details. 56 | -------------------------------------------------------------------------------- /assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "storybook-addon-mock", 3 | "description": "A monorepo for storybook-addon-mock", 4 | "private": true, 5 | "workspaces": [ 6 | "packages/*" 7 | ], 8 | "scripts": { 9 | "clean": "rm -rf dist", 10 | "build": "yarn run addon:build && yarn run docs:build", 11 | "lint": "yarn workspaces run lint", 12 | "lint:fix": "yarn workspaces run lint:fix", 13 | "test": "yarn workspaces run test", 14 | "ci": "yarn run lint && yarn run test && yarn run addon:build && yarn run docs:build", 15 | "addon:build": "yarn workspace storybook-addon-mock run build", 16 | "docs:start": "yarn workspace storybook-addon-mock-docs run storybook", 17 | "docs:build": "yarn workspace storybook-addon-mock-docs run build", 18 | "dedup": "yarn-deduplicate" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "https://github.com/nutboltu/storybook-addon-mock.git" 23 | }, 24 | "keywords": [ 25 | "storybook", 26 | "mock", 27 | "http-mock", 28 | "fetch-mock", 29 | "xhr-mock", 30 | "mock-data", 31 | "storybook-addon", 32 | "data-state", 33 | "storybook-mock-request", 34 | "storybook-mock-fetch", 35 | "mock-request" 36 | ], 37 | "devDependencies": { 38 | "@babel/core": "^7.21.4", 39 | "@babel/eslint-parser": "^7.21.3", 40 | "eslint": "^8.37.0", 41 | "eslint-config-prettier": "^8.8.0", 42 | "eslint-plugin-import": "^2.27.5", 43 | "eslint-plugin-jsx-a11y": "^6.7.1", 44 | "eslint-plugin-prettier": "^4.2.1", 45 | "eslint-plugin-react": "^7.32.2", 46 | "jest": "^29.5.0", 47 | "prettier": "^2.8.7", 48 | "prop-types": "^15.8.1", 49 | "webpack": "^5.77.0", 50 | "yarn-deduplicate": "^6.0.1" 51 | } 52 | } -------------------------------------------------------------------------------- /packages/mock-addon-docs/.eslintignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | 4 | #build files 5 | dist 6 | 7 | # ignore static storybook 8 | 9 | storybook-static -------------------------------------------------------------------------------- /packages/mock-addon-docs/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint:recommended", 4 | "plugin:react/recommended", 5 | "plugin:prettier/recommended" 6 | ], 7 | "parser": "@babel/eslint-parser", 8 | "parserOptions": { 9 | "requireConfigFile": false, 10 | "ecmaFeatures": { 11 | "jsx": true, 12 | "modules": true 13 | } 14 | }, 15 | "env": { 16 | "browser": true, 17 | "es6": true, 18 | "node": true, 19 | "jest": true 20 | }, 21 | "plugins": [ 22 | "react" 23 | ], 24 | "rules": { 25 | "import/no-extraneous-dependencies": 0, 26 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 27 | "react/no-array-index-key": 0 28 | } 29 | } -------------------------------------------------------------------------------- /packages/mock-addon-docs/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 4, 4 | "semi": true, 5 | "singleQuote": true 6 | } -------------------------------------------------------------------------------- /packages/mock-addon-docs/.storybook/main.js: -------------------------------------------------------------------------------- 1 | const config = { 2 | stories: [ 3 | '../stories/**/*.mdx', 4 | '../stories/**/stories.@(js|jsx|mjs|ts|tsx)', 5 | ], 6 | addons: [ 7 | '../../mock-addon/src/preset/manager.js', 8 | '@storybook/addon-links', 9 | '@storybook/addon-essentials', 10 | '@storybook/addon-interactions', 11 | ], 12 | framework: { 13 | name: '@storybook/react-vite', 14 | options: {}, 15 | }, 16 | docs: { 17 | autodocs: 'tag', 18 | } 19 | }; 20 | export default config; 21 | -------------------------------------------------------------------------------- /packages/mock-addon-docs/.storybook/preview.jsx: -------------------------------------------------------------------------------- 1 | import {withRoundTrip} from "storybook-addon-mock/src/withRoundTrip"; 2 | 3 | const Preview = { 4 | parameters: { 5 | options: { 6 | storySort: { 7 | order: ['Docs', ['Introduction', 'Installation', 'User guide']], 8 | includeName: true 9 | } 10 | }, 11 | mockAddonConfigs: { 12 | globalMockData: [], 13 | refreshStoryOnUpdate: true, 14 | disableUsingOriginal: false, 15 | }, 16 | }, 17 | decorators: [withRoundTrip], 18 | } 19 | 20 | export default Preview -------------------------------------------------------------------------------- /packages/mock-addon-docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "storybook-addon-mock-docs", 3 | "version": "1.0.0", 4 | "description": "A package with documentation and example for storybook-addon-mock", 5 | "main": "index.js", 6 | "scripts": { 7 | "lint": "eslint .", 8 | "lint:fix": "yarn run lint --fix", 9 | "test": "echo \"Error: no test specified\"", 10 | "storybook": "storybook dev -p 6006", 11 | "build": "storybook build", 12 | "serve-storybook": "serve storybook-static" 13 | }, 14 | "keywords": [], 15 | "author": "Farhad Yasir(nutboltu)", 16 | "license": "MIT", 17 | "devDependencies": { 18 | "@storybook/addon-actions": "^8.0.8", 19 | "@storybook/addon-essentials": "^8.0.8", 20 | "@storybook/addon-interactions": "^8.0.8", 21 | "@storybook/addon-links": "^8.0.8", 22 | "@storybook/react": "^8.0.8", 23 | "@storybook/react-vite": "^8.0.8", 24 | "@storybook/storybook-deployer": "^2.8.16", 25 | "storybook": "^8.0.8" 26 | }, 27 | "dependencies": { 28 | "axios": "^1.3.4", 29 | "react": "^18.2.0", 30 | "react-code-blocks": "^0.0.9-0", 31 | "react-dom": "^18.2.0", 32 | "superagent": "^8.0.9", 33 | "vite": "^5.2.8" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/mock-addon-docs/stories/assets/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /packages/mock-addon-docs/stories/docs/advanced-setup.mdx: -------------------------------------------------------------------------------- 1 | 2 | import { Meta } from '@storybook/addon-docs'; 3 | import { Footer } from './footer'; 4 | 5 | 6 | 7 | 14 | 15 |

Advanced setup

16 | 17 |

1. Global configuration

18 | 19 | You can set global configuration for the addon. Go to the `.storybook/preview.jsx` file and add `mockAddonConfigs` fields with the following properties. 20 | 21 | 22 | 23 | | Property | Description | Default | 24 | | ------------------------ | :----------------------------------------------------------------------------- | :------ | 25 | | `globalMockData` | An array of mock objects which will add in every story | [] | 26 | | `ignoreQueryParams` | Whether or not to ignore query parameters globally | false | 27 | | `refreshStoryOnUpdate` | This property re-renders the story if there's any data changes | false | 28 | | `disableUsingOriginal` | This property disables the toggle (on/off) option to use the original endpoint | false | 29 | | `disable` | This property disables the panel from all the stories | false | 30 | 31 | 32 | ```js 33 | export const parameters = { 34 | ... 35 | mockAddonConfigs: { 36 | globalMockData: [{ 37 | // An array of mock objects which will add in every story 38 | url: 'http://localhost:0000', 39 | method: 'PUT', 40 | status: 201, 41 | response: {}, 42 | }], 43 | ignoreQueryParams: true, // Whether or not to ignore query parameters globally 44 | refreshStoryOnUpdate: true, // This property re-renders the story if there's any data changes 45 | disableUsingOriginal: false, // This property disables the toggle (on/off) option to use the original endpoint 46 | disable: true, // This property disables the panel from all the stories 47 | } 48 | ... 49 | } 50 | ``` 51 | 52 | 53 |

2. Story and Component parameters

54 | 55 | We can set mock data for a single story with the parameters 56 | 57 | ```js 58 | 59 | import React from 'react'; 60 | import { FetchExample } from './index'; 61 | 62 | export default { 63 | title: 'Examples/Fetch', 64 | component: FetchExample, 65 | }; 66 | 67 | const Template = () => ; 68 | 69 | export const FetchCall = Template.bind({}); 70 | 71 | FetchCall.parameters = { 72 | mockData: [ 73 | { 74 | url: 'https://jsonplaceholder.typicode.com/todos/1', 75 | method: 'GET', 76 | status: 200, 77 | response: { 78 | data: 'Hello storybook-addon-mock!', 79 | }, 80 | }, 81 | ], 82 | }; 83 | 84 | ``` 85 | 86 | We can set mock data for all stories of a component using the parameters key on the default CSF export 87 | 88 | ```js 89 | import React from 'react'; 90 | import { FetchExample } from './index'; 91 | 92 | export default { 93 | title: 'Examples/Fetch', 94 | component: FetchExample, 95 | parameters: { 96 | mockData: [ 97 | { 98 | url: 'https://jsonplaceholder.typicode.com/todos/1', 99 | method: 'GET', 100 | status: 200, 101 | response: { 102 | data: 'Hello storybook-addon-mock!', 103 | }, 104 | }, 105 | ], 106 | }, 107 | }; 108 | 109 | const Template = () => ; 110 | 111 | export const FetchCall = Template.bind({}); 112 | 113 | ``` 114 | 115 |

3. Custom response function

116 | 117 | You can customise the response using the custom response function. Response function is a function that contains request object as a parameter. 118 | You can return custom response depends on the request payload. 119 | 120 | ```js 121 | import React from 'react'; 122 | import { FetchExample } from './index'; 123 | 124 | export default { 125 | title: 'Examples/Fetch', 126 | component: FetchExample, 127 | }; 128 | 129 | const Template = () => ; 130 | 131 | export const FetchCall = Template.bind({}); 132 | 133 | FetchCall.parameters = { 134 | mockData: [ 135 | url: 'https://jsonplaceholder.typicode.com/todos/1', 136 | method: 'GET', 137 | status: 200, 138 | response: (request) => { 139 | const { body, searchParams } = request; 140 | 141 | if (searchParams.id == 1) { 142 | return { 143 | data: 'Custom data for id 1', 144 | }; 145 | } else if (body.name === 'mock') { 146 | return { 147 | data: 'Custom data for name mock', 148 | }; 149 | } 150 | return { 151 | data: 'Default data', 152 | }; 153 | }, 154 | ], 155 | }; 156 | ``` 157 |

2. Disable the panel for a story

158 | 159 | ```js 160 | import React from 'react'; 161 | import { FetchExample } from './index'; 162 | 163 | export default { 164 | title: 'Examples/Fetch', 165 | component: FetchExample, 166 | }; 167 | 168 | const Template = () => ; 169 | 170 | export const FetchCall = Template.bind({}); 171 | 172 | FetchCall.parameters = { 173 | mockAddonConfigs: { disable: true } 174 | }; 175 | ``` 176 | 177 |