diff --git a/docs/README.md b/docs/README.md index 1db743790c..590197cb95 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,18 +6,12 @@ Welcome to the React Cosmos documentation! ## Getting started -Bundler integrations +Choose a dedicated guide for integrating with a specific bundler, framework, or a custom setup: - [Vite](getting-started/vite.md) - [Webpack](getting-started/webpack.md) - -Framework integrations - - [Next.js](getting-started/next.md) - [Create React App](getting-started/create-react-app.md) - -Other integrations - - [React Native](getting-started/react-native.md) - [Custom bundler](getting-started/custom-bundler.md) @@ -31,6 +25,13 @@ Other integrations - [Static export](usage/static-export.md) - [Node.js API](usage/node-api.md) +## Plugins + +- [Plugin config](plugins/plugin-config.md) +- [Server plugins](plugins/server-plugins.md) +- [UI plugins](plugins/ui-plugins.md) +- [Fixture plugins](plugins/fixture-plugins.md) + --- [Join us on Discord](https://discord.gg/3X95VgfnW5) for feedback, questions and ideas. diff --git a/docs/getting-started/react-native.md b/docs/getting-started/react-native.md index e28f10a7a2..a42c45f470 100644 --- a/docs/getting-started/react-native.md +++ b/docs/getting-started/react-native.md @@ -14,7 +14,7 @@ Add `cosmos` script to package.json: ```json "scripts": { - "cosmos": "cosmos" + "cosmos": "cosmos-native" } ``` diff --git a/docs/getting-started/vite.md b/docs/getting-started/vite.md index 07018731b9..ffa062d47e 100644 --- a/docs/getting-started/vite.md +++ b/docs/getting-started/vite.md @@ -70,7 +70,7 @@ Vite-related settings you can optionally customize in your Cosmos config: | Option | Description | Default | | ----------------- | ------------------------------------------------------------------------------ | ---------------------------------------- | | `vite.configPath` | Path to Vite config. Set to false to disable reading it from the default path. | `"vite.config.js"` or `"vite.config.ts"` | -| `vite.indexPath` | Path to index module (eg. `"src/my-index.tsx"`). | _detects common index/main module paths_ | +| `vite.indexPath` | Path to index module (eg. `"src/my-index.tsx"`). | Detects common index/main module paths. | | `vite.port` | Vite renderer port. | `5050` | --- diff --git a/docs/plugins/fixture-plugins.md b/docs/plugins/fixture-plugins.md new file mode 100644 index 0000000000..1f200dd352 --- /dev/null +++ b/docs/plugins/fixture-plugins.md @@ -0,0 +1,27 @@ +# Fixture plugins + +While there's no formal way to package renderer plugins (like with server and UI plugins), you can tap into the fixture context to read and write fixture state that is synchronized between the renderer and the Cosmos UI. + +The [Viewport](../usage/fixtures.md#viewport) decorator is a good example. + +## `FixtureContext` + +```jsx +import { FixtureContext } from 'react-cosmos/client'; + +export function MagicDecorator({ children }) { + const { fixtureState, setFixtureState } = React.useContext(FixtureContext); + + // Read or write the fixture state based on user events or other side effects. + + return children; +} +``` + +- The standard fixture state object contains the `props`, `classState` and `controls` fields. They're used to construct the Props, Class State and Control panels in the Cosmos UI. +- You can extend the fixture state with extra fields. For example the [Viewport](../usage/fixtures.md#viewport) decorator sets the `fixtureState.viewport` field used by the responsive preview plugin in the Cosmos UI. +- Generally a fixture plugin will pair with a Cosmos UI plugin to syncronize data between the renderer, which runs inside the user's code, and the Cosmos UI. + +--- + +[Join us on Discord](https://discord.gg/3X95VgfnW5) for feedback, questions and ideas. diff --git a/docs/plugins/plugin-config.md b/docs/plugins/plugin-config.md new file mode 100644 index 0000000000..94a858af09 --- /dev/null +++ b/docs/plugins/plugin-config.md @@ -0,0 +1,52 @@ +# Plugin config + +This is a guide for creating Cosmos plugins. + +Create a `cosmos.plugin.json` file: + +```json +{ + "name": "Magic plugin", + "server": "serverPlugin.js", + "ui": "uiPlugin.js" +} +``` + +This JSON config is the plugin's entry point. + +A Cosmos plugin can contain a **server plugin** and a **UI plugin**. At least one is required, along with a plugin name. The `server` and `ui` paths are resolved relative to the config's parent directory. + +To enable a Cosmos plugin add it to the `plugins` option in the `cosmos.config.json` of the host project: + +```json +{ + "plugins": ["../packages/magic-plugin/cosmos.plugin.json"] +} +``` + +If the Cosmos plugin is an NPM package, add the name of the package to `plugins` instead: + +```json +{ + "plugins": ["react-cosmos-plugin-magic"] +} +``` + +To publish a Cosmos plugin as an NPM package, set the `main` field in its `package.json` to `"cosmos.plugin.json"` (or a different path where the Cosmos plugin config is located): + +```json +{ + "name": "react-cosmos-plugin-magic", + "version": "1.0.0", + "main": "cosmos.plugin.json" +} +``` + +See the individual guides for each plugin type: + +- [Server plugins](server-plugins.md) +- [UI plugins](ui-plugins.md) + +--- + +[Join us on Discord](https://discord.gg/3X95VgfnW5) for feedback, questions and ideas. diff --git a/docs/plugins/server-plugins.md b/docs/plugins/server-plugins.md new file mode 100644 index 0000000000..566eb04a54 --- /dev/null +++ b/docs/plugins/server-plugins.md @@ -0,0 +1,62 @@ +# Server plugins + +This is a guide for creating Cosmos server plugins. + +## Boilerplate + +The `server` field in [`cosmos.plugin.json`](./plugin-config.md) points to a module like this: + +```js +export default { + name: 'magic-plugin', + + async config({ cosmosConfig }) { + // An opportunity to alter the user's Cosmos config + return cosmosConfig; + }, + + async devServer({ cosmosConfig, platform, httpServer, expressApp }) { + // Dev server plugin + }, + + async export({ cosmosConfig }) { + // Static export plugin + }, +}; +``` + +### `config` + +| Argument | Description | +| -------------- | ----------------------------------------------------------------------- | +| `cosmosConfig` | The user's [Cosmos config](../usage/configuration.md#cosmosconfigjson). | +| `command` | `"dev"` or `"export"`. | +| `platform` | `"web"` or `"native"`. | + +The `config` hook is called before both `devServer` and `export` hooks. It allows overriding the user's Cosmos config. Setting the `rendererUrl` config option is a common use case. + +### `devServer` + +| Argument | Description | +| -------------- | --------------------------------------------------------------------------------------------- | +| `cosmosConfig` | The user's [Cosmos config](../usage/configuration.md#cosmosconfigjson). | +| `platform` | `"web"` or `"native"`. | +| `httpServer` | The [http.Server](https://nodejs.org/api/http.html#class-httpserver) instance used by Cosmos. | +| `expressApp` | The [Express App](https://expressjs.com/en/4x/api.html#app) instance used by Cosmos. | +| `sendMessage` | Send a message to the Cosmos UI. | + +A hook for starting the renderer dev server alongside the Cosmos server. + +For example in the Webpack plugin the Webpack compiler is attached to Cosmos' internal Express app, having the renderer run on the same port as the Cosmos server. In contract, the Vite plugin starts the Vite dev server independently and in this case you end up using two ports—one for the Cosmos server and one for the Vite renderer. + +### `export` + +| Argument | Description | +| -------------- | ----------------------------------------------------------------------- | +| `cosmosConfig` | The user's [Cosmos config](../usage/configuration.md#cosmosconfigjson). | + +A hook for exporting the user's fixtures and decorators into a static Cosmos renderer that the static Cosmos UI connects to. + +--- + +[Join us on Discord](https://discord.gg/3X95VgfnW5) for feedback, questions and ideas. diff --git a/docs/plugins/ui-plugins.md b/docs/plugins/ui-plugins.md new file mode 100644 index 0000000000..ffd3059260 --- /dev/null +++ b/docs/plugins/ui-plugins.md @@ -0,0 +1,9 @@ +# UI plugins + +This is a guide for creating Cosmos UI plugins. + +WIP. + +--- + +[Join us on Discord](https://discord.gg/3X95VgfnW5) for feedback, questions and ideas. diff --git a/docs/usage/configuration.md b/docs/usage/configuration.md index 9b102fc304..4c807e0379 100644 --- a/docs/usage/configuration.md +++ b/docs/usage/configuration.md @@ -1,12 +1,30 @@ # Configuration -The React Cosmos config is a **JSON** file, so it can only contain serializable values. This design decision is meant to discourage complex configuration, make it easy to embed config options into the React Cosmos UI, and enable visual config editing. +## CLI -By default, Cosmos reads `cosmos.config.json` from your root directory. You can pass a `--config` CLI arg for a custom config path. +- The `cosmos` command starts the dev server. +- The `cosmos-native` command starts the dev server for a React Native project. +- The `cosmos-export` command generates a static export. -## Config schema +Some things can be customized using CLI arguments: -The best way to learn about the available options in the Cosmos config is to use [config.schema.json](../../packages/react-cosmos/config.schema.json). +| Argument | Description | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--config` | Specify a custom config path. By default Cosmos reads `cosmos.config.json` from your root directory. | +| `--root-dir` | Specify a root directory for your project. By default the root directory is the parent directory of your Cosmos config or the current working directory in the absence of a Cosmos config. | +| `--lazy` | Dynamically import user modules. By default all fixture and decorator modules are imported statically and bundled together. | +| `--expose-imports` | Expose user imports and config required for the Cosmos renderer. Use with React Native and in custom integrations. When a path is specified it requires a file extension (eg. `"src/cosmos.imports.ts"`). | +| `--port` | Convenient way to override the Cosmos dev server port. | + +There rest of the things are customized using the large number of options in the Cosmos config. + +## `cosmos.config.json` + +The Cosmos config is a **JSON** file, so it can only contain serializable values. This design decision is meant to discourage complex configuration, make it easy to embed config options into the Cosmos UI, and enable visual config editing. + +### Config schema + +**The best way to learn about the available options in the Cosmos config is to use [config.schema.json](../../packages/react-cosmos/config.schema.json).** The schema is human readable, but you can also enhance your config with autocomplete in code editors like VS Code. @@ -39,9 +57,9 @@ Alternatively, you can reference the local Cosmos config schema in your workspac ] ``` -## Custom viewports +### Custom viewports -`responsivePreview` is a plugin included by default and you can customize it through the Cosmos config. +`responsivePreview` is a plugin included by default and you can customize it through the Cosmos config: ```json { diff --git a/docs/usage/fixtures.md b/docs/usage/fixtures.md index 314048d8d0..270cb20204 100644 --- a/docs/usage/fixtures.md +++ b/docs/usage/fixtures.md @@ -106,6 +106,20 @@ export default () => { > **Note** `useValue` and `useSelect` (and Cosmos in general) work great with TypeScript. +### `` + +By using the Viewport decorator a fixture can trigger the responsive preview in the Cosmos UI on a specific resolution. + +```jsx +import { Viewport } from 'react-cosmos/client'; + +export default ( + + + +); +``` + --- [Join us on Discord](https://discord.gg/3X95VgfnW5) for feedback, questions and ideas. diff --git a/packages/react-cosmos-plugin-webpack/src/server/webpackConfig/getUserWebpackConfig.ts b/packages/react-cosmos-plugin-webpack/src/server/webpackConfig/getUserWebpackConfig.ts index d06ad93291..fc0ed5d47c 100644 --- a/packages/react-cosmos-plugin-webpack/src/server/webpackConfig/getUserWebpackConfig.ts +++ b/packages/react-cosmos-plugin-webpack/src/server/webpackConfig/getUserWebpackConfig.ts @@ -70,6 +70,8 @@ async function getBaseWebpackConfig( const module = await importModule<{ default: WebpackConfig }>(configPath); const webpackConfig = module.default; + // The --env flag matches the webpack CLI convention + // https://webpack.js.org/api/cli/#env const cliArgs = getCliArgs(); return typeof webpackConfig === 'function' ? await webpackConfig(cliArgs.env || getWebpackNodeEnv(), cliArgs) diff --git a/packages/react-cosmos/config.schema.json b/packages/react-cosmos/config.schema.json index 9a84aa38d4..635207a041 100644 --- a/packages/react-cosmos/config.schema.json +++ b/packages/react-cosmos/config.schema.json @@ -16,7 +16,7 @@ "minLength": 1 }, "detectLocalPlugins": { - "description": "Automatically detect and load local plugins", + "description": "Automatically detect and load local plugins [default: true].", "type": "boolean" }, "disablePlugins": {