From bff6546f7fcd9b4c924f6114c4010124092cebcc Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Sat, 17 Nov 2018 00:32:03 -0800 Subject: [PATCH 1/9] add basic index for monorepos --- bin/storybook_to_ghpages | 10 ++++++-- src/build-monorepo-index.js | 35 ++++++++++++++++++++++++++++ src/monorepo-index.css | 46 +++++++++++++++++++++++++++++++++++++ src/storybook.svg | 45 ++++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 src/build-monorepo-index.js create mode 100644 src/monorepo-index.css create mode 100644 src/storybook.svg diff --git a/bin/storybook_to_ghpages b/bin/storybook_to_ghpages index 72a05ad..ccb2116 100755 --- a/bin/storybook_to_ghpages +++ b/bin/storybook_to_ghpages @@ -8,6 +8,7 @@ const glob = require('glob'); const packageJson = require(path.resolve('./package.json')); const argv = require('yargs').argv; const parseRepo = require('parse-repo'); +const buildMonorepoIndex = require('../src/build-monorepo-index') const SKIP_BUILD = Boolean(argv['existing-output-dir']) const OUTPUT_DIR = argv.out || argv['existing-output-dir'] || 'out' + Math.ceil(Math.random() * 9999); @@ -75,20 +76,25 @@ function buildSubPackage(origDir, dir) { shell.mkdir('-p', outputPath); shell.cp('-r', builtStorybook, outputPath); shell.rm('-rf', builtStorybook); + + return subPackage; } if (!SKIP_BUILD) { if (argv.packages) { const origDir = process.cwd(); - glob + const packages = glob .sync(path.join(origDir, argv.packages, '**/package.json'), { ignore: '**/node_modules/**' }) .map(json => path.dirname(json)) - .map(subPackage => buildSubPackage(origDir, subPackage)); + .map(subPackage => buildSubPackage(origDir, subPackage)) + .filter(subPackage => subPackage); shell.cd(origDir); + + buildMonorepoIndex(packages, OUTPUT_DIR) } else { console.log('=> Building storybook'); buildStorybook(packageJson); diff --git a/src/build-monorepo-index.js b/src/build-monorepo-index.js new file mode 100644 index 0000000..73b01c8 --- /dev/null +++ b/src/build-monorepo-index.js @@ -0,0 +1,35 @@ +const shell = require('shelljs'); +const fs = require('fs') +const path = require('path') + +module.exports = function buildMonorepoIndex(packages, outputDir) { + const packageRows = packages.map(package => ` +
+ ${package.name} + ${package.description} +
+ `) + const index = ` + + + + + + Page Title + + + + + +
+ ${packageRows.join('')} +
+ + + ` + + console.log(`=> Building index.html for monorepo`); + fs.writeFileSync(path.join(outputDir, 'index.html'), index); + shell.cp(path.join(__dirname, 'storybook.svg'), path.join(outputDir, 'storybook.svg')); + shell.cp(path.join(__dirname, 'mono-repo-index.css'), path.join(outputDir, 'mono-repo-index.css')); +} \ No newline at end of file diff --git a/src/monorepo-index.css b/src/monorepo-index.css new file mode 100644 index 0000000..00d070a --- /dev/null +++ b/src/monorepo-index.css @@ -0,0 +1,46 @@ +html { + height: 100%; +} + +body { + display: flex; + flex-direction: column; + justify-content: center; + min-height: 60%; + margin: 4rem; +} + +.content { + display: flex; + flex-direction: column; + width: fit-content; + justify-content: center; + margin: 3rem auto; +} + +.banner { + max-width: 600px; + width: 100%; + margin: 0 auto; +} + +.package-row { + background-color: #eee; + border-radius: 5%; + box-shadow: 0px 10px 1px #ddd, 0 10px 20px #ccc; + margin-bottom: 1.5rem; + color: #666; + display: flex +} + +.package-row a { + padding: 2rem; +} + +.package-row span { + padding: 2rem 2rem 2rem 1rem; + border-top-right-radius: 5%; + border-bottom-right-radius: 5%; + background: #e9e9e9; + flex-grow: 1; +} \ No newline at end of file diff --git a/src/storybook.svg b/src/storybook.svg new file mode 100644 index 0000000..fe5e4f5 --- /dev/null +++ b/src/storybook.svg @@ -0,0 +1,45 @@ + +storybook-logo-final +Created using Figma + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 0285ae6684831e70c3791da9715a72a4c16dce32 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Sat, 17 Nov 2018 01:06:01 -0800 Subject: [PATCH 2/9] allow user to supply a path to a function that will generate the index instaed --- bin/storybook_to_ghpages | 2 +- src/build-monorepo-index.js | 52 +++++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/bin/storybook_to_ghpages b/bin/storybook_to_ghpages index ccb2116..2f3234e 100755 --- a/bin/storybook_to_ghpages +++ b/bin/storybook_to_ghpages @@ -94,7 +94,7 @@ if (!SKIP_BUILD) { shell.cd(origDir); - buildMonorepoIndex(packages, OUTPUT_DIR) + buildMonorepoIndex(packages, argv['monorepo-index-generator'], OUTPUT_DIR); } else { console.log('=> Building storybook'); buildStorybook(packageJson); diff --git a/src/build-monorepo-index.js b/src/build-monorepo-index.js index 73b01c8..7064e57 100644 --- a/src/build-monorepo-index.js +++ b/src/build-monorepo-index.js @@ -1,14 +1,16 @@ const shell = require('shelljs'); -const fs = require('fs') -const path = require('path') +const fs = require('fs'); +const path = require('path'); -module.exports = function buildMonorepoIndex(packages, outputDir) { - const packageRows = packages.map(package => ` -
- ${package.name} - ${package.description} -
- `) +function generateHTML(packages) { + const packageRows = packages.map( + package => ` +
+ ${package.name} + ${package.description} +
+ ` + ); const index = ` @@ -26,10 +28,34 @@ module.exports = function buildMonorepoIndex(packages, outputDir) { - ` + `; + + return index; +} + +module.exports = function buildMonorepoIndex(packages, customHTMLGenerate, outputDir) { + let index; console.log(`=> Building index.html for monorepo`); + + if (customHTMLGenerate) { + const fn = require(path.join(process.cwd(), customHTMLGenerate)) + + if (typeof fn === 'function') { + index = fn(packages, outputDir) + } + } else { + index = generateHTML(packages) + + shell.cp( + path.join(__dirname, 'storybook.svg'), + path.join(outputDir, 'storybook.svg') + ); + shell.cp( + path.join(__dirname, 'mono-repo-index.css'), + path.join(outputDir, 'mono-repo-index.css') + ); + } + fs.writeFileSync(path.join(outputDir, 'index.html'), index); - shell.cp(path.join(__dirname, 'storybook.svg'), path.join(outputDir, 'storybook.svg')); - shell.cp(path.join(__dirname, 'mono-repo-index.css'), path.join(outputDir, 'mono-repo-index.css')); -} \ No newline at end of file +}; From 811a9afca765b9804b8dd557188b090c304e0b98 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Sat, 17 Nov 2018 01:13:34 -0800 Subject: [PATCH 3/9] document it --- README.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b549d9b..6e0bb76 100644 --- a/README.md +++ b/README.md @@ -53,12 +53,23 @@ npm run deploy-storybook -- --existing-output-dir=.out If you manage a monorepo with multiple storybooks you can you pass the `packages` flag to `deploy-storybook` to scan a directory for `package.json`s. -The following command will search the `packages` directory for packages. +The following command will search the `packages` directory for packages. It will also generate a default `index.html` that links to all of the loaded storybooks. ```sh npm run deploy-storybook -- --packages packages ``` +### Customize Monorepo `index.html` + +To customize the monorepo `index.html` you can pass the `packages` flag to `deploy-storybook`. This function will receive the following arguments: + +- an array of all the `package.json` data from the loaded storybooks as the first argument +- the output directory + +```sh +npm run deploy-storybook -- --monorepo-index-generator my-custom-generator.js +``` + ### Deploying Storybook as part of a CI service To deploy Storybook as part of a CI step, pass the `ci` flag to `npm run deploy-storybook`. From e58720a9d006f730dd34822edca7be9a38a73f6a Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Sat, 17 Nov 2018 01:21:45 -0800 Subject: [PATCH 4/9] fix path --- src/build-monorepo-index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/build-monorepo-index.js b/src/build-monorepo-index.js index 7064e57..a04daf9 100644 --- a/src/build-monorepo-index.js +++ b/src/build-monorepo-index.js @@ -19,7 +19,7 @@ function generateHTML(packages) { Page Title - + @@ -52,8 +52,8 @@ module.exports = function buildMonorepoIndex(packages, customHTMLGenerate, outpu path.join(outputDir, 'storybook.svg') ); shell.cp( - path.join(__dirname, 'mono-repo-index.css'), - path.join(outputDir, 'mono-repo-index.css') + path.join(__dirname, 'monorepo-index.css'), + path.join(outputDir, 'monorepo-index.css') ); } From 3e20aaf567384d85da06c8b42984dc493347192a Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Sun, 2 Dec 2018 17:30:39 -0800 Subject: [PATCH 5/9] use correct package.json From 99aca1f4ee22b96c204ab1fac71da9096e7d85c5 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Fri, 23 Nov 2018 13:14:54 -0800 Subject: [PATCH 6/9] make it prettier --- src/build-monorepo-index.js | 30 +++++++----- src/monorepo-index.css | 97 ++++++++++++++++++++++++++++++++----- 2 files changed, 105 insertions(+), 22 deletions(-) diff --git a/src/build-monorepo-index.js b/src/build-monorepo-index.js index a04daf9..93fd2d8 100644 --- a/src/build-monorepo-index.js +++ b/src/build-monorepo-index.js @@ -2,13 +2,17 @@ const shell = require('shelljs'); const fs = require('fs'); const path = require('path'); +const colors = ['purple', 'pink', 'orange', 'green', 'blue', 'red']; + function generateHTML(packages) { - const packageRows = packages.map( - package => ` -
- ${package.name} - ${package.description} -
+ const packageRows = [...packages, ...packages, ...packages, ...packages].map( + (package, index) => ` + + + ${package.name} + + ${package.description} + ` ); const index = ` @@ -33,19 +37,23 @@ function generateHTML(packages) { return index; } -module.exports = function buildMonorepoIndex(packages, customHTMLGenerate, outputDir) { +module.exports = function buildMonorepoIndex( + packages, + customHTMLGenerate, + outputDir +) { let index; console.log(`=> Building index.html for monorepo`); - + if (customHTMLGenerate) { - const fn = require(path.join(process.cwd(), customHTMLGenerate)) + const fn = require(path.join(process.cwd(), customHTMLGenerate)); if (typeof fn === 'function') { - index = fn(packages, outputDir) + index = fn(packages, outputDir); } } else { - index = generateHTML(packages) + index = generateHTML(packages); shell.cp( path.join(__dirname, 'storybook.svg'), diff --git a/src/monorepo-index.css b/src/monorepo-index.css index 00d070a..17964b3 100644 --- a/src/monorepo-index.css +++ b/src/monorepo-index.css @@ -7,7 +7,7 @@ body { flex-direction: column; justify-content: center; min-height: 60%; - margin: 4rem; + margin: 2rem; } .content { @@ -21,26 +21,101 @@ body { .banner { max-width: 600px; width: 100%; - margin: 0 auto; + margin: 3rem auto; } .package-row { - background-color: #eee; - border-radius: 5%; - box-shadow: 0px 10px 1px #ddd, 0 10px 20px #ccc; - margin-bottom: 1.5rem; + margin-bottom: 2rem; color: #666; - display: flex + display: flex; + align-items: stretch; + text-decoration: none; + transition: 0.3s; +} + +.package-row:hover { + box-shadow: 0 15px 20px #bbb; } -.package-row a { +.package-row .title { padding: 2rem; + color: white; + border-top-left-radius: 5%; + border-bottom-left-radius: 5%; + font-weight: bold; } -.package-row span { +.package-row .description { padding: 2rem 2rem 2rem 1rem; border-top-right-radius: 5%; border-bottom-right-radius: 5%; - background: #e9e9e9; + background: #f1f1f1; flex-grow: 1; -} \ No newline at end of file + box-shadow: 0px 10px 0 #d8d8d8; + text-align: center; +} + +.package-row:active .description { + background: #d8d8d8; + box-shadow: 0px 10px 0 #bebebe; +} + +.is-purple { + background: #b57ee5; + box-shadow: 0px 10px 0 #9c65cc; +} + +.package-row:active .is-purple { + background: #9c65cc; + box-shadow: 0px 10px 0 #824bb2; +} + +.is-pink { + background: #f1618c; + box-shadow: 0px 10px 0 #d84873; +} + +.package-row:active .is-pink { + background: #d84873; + box-shadow: 0px 10px 0 #be2e59; +} + +.is-orange { + background: #f3ad38; + box-shadow: 0px 10px 0 #da941f; +} + +.package-row:active .is-orange { + background: #da941f; + box-shadow: 0px 10px 0 #c07a05; +} + +.is-green { + background: #a2e05e; + box-shadow: 0px 10px 0 #89c745; +} + +.package-row:active .is-green { + background: #89c745; + box-shadow: 0px 10px 0 #6fad2b; +} + +.is-blue { + background: #6dabf5; + box-shadow: 0px 10px 0 #5492dc; +} + +.package-row:active .is-blue { + background: #5492dc; + box-shadow: 0px 10px 0 #3a78c2; +} + +.is-red { + background: #f16161; + box-shadow: 0px 10px 0 #d84848; +} + +.package-row:active .is-red { + background: #d84848; + box-shadow: 0px 10px 0 #be2e2e; +} From 79927a6a896e5b96bdc29e0b576965936064ae9c Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Fri, 23 Nov 2018 13:42:35 -0800 Subject: [PATCH 7/9] remove test code --- src/build-monorepo-index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build-monorepo-index.js b/src/build-monorepo-index.js index 93fd2d8..248cc04 100644 --- a/src/build-monorepo-index.js +++ b/src/build-monorepo-index.js @@ -5,7 +5,7 @@ const path = require('path'); const colors = ['purple', 'pink', 'orange', 'green', 'blue', 'red']; function generateHTML(packages) { - const packageRows = [...packages, ...packages, ...packages, ...packages].map( + const packageRows = packages.map( (package, index) => ` From 139b64078f557032d8ed5830a5b4113d45529094 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Fri, 23 Nov 2018 13:44:22 -0800 Subject: [PATCH 8/9] change page title --- src/build-monorepo-index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/build-monorepo-index.js b/src/build-monorepo-index.js index 248cc04..f84ed31 100644 --- a/src/build-monorepo-index.js +++ b/src/build-monorepo-index.js @@ -21,7 +21,7 @@ function generateHTML(packages) { - Page Title + Storybooks From b5a5d56ef4a48ec8b661c6991d7edfbf2409aa10 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Sun, 2 Dec 2018 18:44:19 -0800 Subject: [PATCH 9/9] update docs --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 6e0bb76..55a145f 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,13 @@ Install Storybook Deployer with: ``` npm i @storybook/storybook-deployer --save-dev ``` + Then add a NPM script like this: ```json { "scripts": { - "deploy-storybook": "storybook-to-ghpages", + "deploy-storybook": "storybook-to-ghpages" } } ``` @@ -28,7 +29,7 @@ If you customize the build configuration with some additional params (like stati ```json { "scripts": { - "build-storybook": "build-storybook -s public", + "build-storybook": "build-storybook -s public" } } ``` @@ -61,7 +62,7 @@ npm run deploy-storybook -- --packages packages ### Customize Monorepo `index.html` -To customize the monorepo `index.html` you can pass the `packages` flag to `deploy-storybook`. This function will receive the following arguments: +To customize the monorepo `index.html` you can pass the `monorepo-index-generator` flag to `deploy-storybook`. This file should export a function that receive the following arguments and returns the html for the page. - an array of all the `package.json` data from the loaded storybooks as the first argument - the output directory @@ -120,11 +121,13 @@ npm run deploy-storybook -- --remote=upstream ``` Or, to specify a target branch and serve your storybook with rawgit instead of gh-pages: + ```sh npm run deploy-storybook -- --branch=feature-branch ``` Or, to specify a source branch other than `master`, pass a `--source-branch` flag to `npm run deploy-storybook`: + ```sh npm run deploy-storybook -- --source-branch=release ```