From 4c1af6db34a562720e76b06b5a988088eb5743b4 Mon Sep 17 00:00:00 2001 From: Tim Brook Date: Thu, 27 Jul 2023 12:10:31 -0500 Subject: [PATCH 1/5] Start making updates to allow publishing to Chromatic --- .storybook/main.js | 6 ++- .storybook/theme.js | 16 ++++---- package-lock.json | 87 ++++++++++++++-------------------------- package.json | 2 +- postcss.config.js | 7 ++-- src/Commands/Publish.php | 6 ++- 6 files changed, 52 insertions(+), 72 deletions(-) diff --git a/.storybook/main.js b/.storybook/main.js index 28bd867..3271b26 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -20,9 +20,13 @@ const config = { name: '@storybook/server-webpack5', options: { quiet: true, - port: 6006 + port: process.env.STORYBOOK_PORT } } }; +if (process.env.STORYBOOK_STATIC_PATH) { + config.staticDirs = [process.env.STORYBOOK_STATIC_PATH]; +} + export default config; diff --git a/.storybook/theme.js b/.storybook/theme.js index 37629ed..0c58054 100644 --- a/.storybook/theme.js +++ b/.storybook/theme.js @@ -1,14 +1,16 @@ import { create } from '@storybook/theming'; -const configTheme = JSON.parse(process.env.STORYBOOK_THEME); - let theme; -if (typeof configTheme !== 'string') { - theme = create(JSON.parse(process.env.STORYBOOK_THEME)); -} else { - if (configTheme === 'custom') { - theme = create(JSON.parse(process.env.STORYBOOK_CUSTOM_THEME)); +if (process.env.STORYBOOK_THEME) { + const configTheme = JSON.parse(process.env.STORYBOOK_THEME); + + if (typeof configTheme !== 'string') { + theme = create(JSON.parse(process.env.STORYBOOK_THEME)); + } else { + if (configTheme === 'custom') { + theme = create(JSON.parse(process.env.STORYBOOK_CUSTOM_THEME)); + } } } diff --git a/package-lock.json b/package-lock.json index 948c3b5..f679e29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3320,14 +3320,6 @@ } } }, - "node_modules/@storybook/addon-actions/node_modules/telejson": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.1.0.tgz", - "integrity": "sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==", - "dependencies": { - "memoizerific": "^1.11.3" - } - }, "node_modules/@storybook/addon-backgrounds": { "version": "7.0.26", "resolved": "https://registry.npmjs.org/@storybook/addon-backgrounds/-/addon-backgrounds-7.0.26.tgz", @@ -3457,11 +3449,6 @@ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, - "node_modules/@storybook/addon-docs/node_modules/@storybook/mdx2-csf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@storybook/mdx2-csf/-/mdx2-csf-1.0.0.tgz", - "integrity": "sha512-dBAnEL4HfxxJmv7LdEYUoZlQbWj9APZNIbOaq0tgF8XkxiIbzqvgB0jhL/9UOrysSDbQWBiCRTu2wOVxedGfmw==" - }, "node_modules/@storybook/addon-essentials": { "version": "7.0.26", "resolved": "https://registry.npmjs.org/@storybook/addon-essentials/-/addon-essentials-7.0.26.tgz", @@ -3766,14 +3753,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/blocks/node_modules/telejson": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.1.0.tgz", - "integrity": "sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==", - "dependencies": { - "memoizerific": "^1.11.3" - } - }, "node_modules/@storybook/builder-manager": { "version": "7.0.26", "resolved": "https://registry.npmjs.org/@storybook/builder-manager/-/builder-manager-7.0.26.tgz", @@ -3931,14 +3910,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/channel-postmessage/node_modules/telejson": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.1.0.tgz", - "integrity": "sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==", - "dependencies": { - "memoizerific": "^1.11.3" - } - }, "node_modules/@storybook/channel-websocket": { "version": "7.0.26", "resolved": "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-7.0.26.tgz", @@ -3963,14 +3934,6 @@ "url": "https://opencollective.com/storybook" } }, - "node_modules/@storybook/channel-websocket/node_modules/telejson": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.1.0.tgz", - "integrity": "sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==", - "dependencies": { - "memoizerific": "^1.11.3" - } - }, "node_modules/@storybook/cli": { "version": "7.0.26", "resolved": "https://registry.npmjs.org/@storybook/cli/-/cli-7.0.26.tgz", @@ -4796,14 +4759,6 @@ "node": ">=8" } }, - "node_modules/@storybook/core-server/node_modules/telejson": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.1.0.tgz", - "integrity": "sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==", - "dependencies": { - "memoizerific": "^1.11.3" - } - }, "node_modules/@storybook/core-webpack": { "version": "7.0.26", "resolved": "https://registry.npmjs.org/@storybook/core-webpack/-/core-webpack-7.0.26.tgz", @@ -4980,13 +4935,10 @@ "node": ">=10" } }, - "node_modules/@storybook/manager-api/node_modules/telejson": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.1.0.tgz", - "integrity": "sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==", - "dependencies": { - "memoizerific": "^1.11.3" - } + "node_modules/@storybook/mdx2-csf": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@storybook/mdx2-csf/-/mdx2-csf-1.1.0.tgz", + "integrity": "sha512-TXJJd5RAKakWx4BtpwvSNdgTDkKM6RkXU8GK34S/LhidQ5Pjz3wcnqb0TxEkfhK/ztbP8nKHqXFwLfa2CYkvQw==" }, "node_modules/@storybook/node-logger": { "version": "7.0.26", @@ -11479,8 +11431,15 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.4", - "license": "MIT", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", + "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -12069,9 +12028,9 @@ } }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz", + "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==", "funding": [ { "type": "opencollective", @@ -12080,10 +12039,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -13990,6 +13953,14 @@ "node": ">=10" } }, + "node_modules/telejson": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/telejson/-/telejson-7.1.0.tgz", + "integrity": "sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==", + "dependencies": { + "memoizerific": "^1.11.3" + } + }, "node_modules/temp": { "version": "0.8.4", "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.4.tgz", diff --git a/package.json b/package.json index 9ad97f7..f1a8d53 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "scripts": { "build-tailwind": "npx tailwindcss -i ./resources/frontend/css/main.css -o ./public/main.css --minify", "build-storybook": "storybook build", - "storybook": "concurrently --i -c \"red,blue,yellow\" -n storybook,watch-components,watch-data \"storybook dev --quiet -s $STORYBOOK_STATIC_PATH -p $STORYBOOK_PORT\" \"npm run watch-components\" \"npm run watch-data\"", + "storybook": "concurrently --i -c \"red,blue,yellow\" -n storybook,watch-components,watch-data \"storybook dev --quiet -p $STORYBOOK_PORT\" \"npm run watch-components\" \"npm run watch-data\"", "watch-components": "chokidar \"$COMPONENTPATH/**/*.blade.php\" -d 0 -c \"cd $PROJECTPATH && php artisan blast:generate-stories --watchEvent={event} -- '{path}';\"", "watch-data": "chokidar \"$COMPONENTPATH/data/**/*.php\" \"$COMPONENTPATH/**/*.md\" -d 0 -c \"cd $PROJECTPATH && php artisan blast:generate-stories;\"", "parse-tailwind": "node ./src/resolveTailwindConfig.js", diff --git a/postcss.config.js b/postcss.config.js index 43be054..818a7d7 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,8 +1,7 @@ module.exports = { plugins: [ - require('postcss-flexbugs-fixes'), require('autoprefixer')({ - flexbox: 'no-2009', - }), - ], + flexbox: 'no-2009' + }) + ] }; diff --git a/src/Commands/Publish.php b/src/Commands/Publish.php index 3bdf080..67139a0 100644 --- a/src/Commands/Publish.php +++ b/src/Commands/Publish.php @@ -19,6 +19,7 @@ class Publish extends Command */ protected $signature = 'blast:publish {--install : Force install dependencies} + {--url= : set the server url used to load the stories} {--o|output-dir=storybook-static : Directory where to store built files}'; /** @@ -62,6 +63,7 @@ public function __construct(Filesystem $filesystem) */ public function handle() { + $serverUrl = $this->option('url', $this->storybookServer); $npmInstall = $this->option('install'); $installMessage = $this->getInstallMessage($npmInstall); $outputDir = $this->option('output-dir'); @@ -116,7 +118,8 @@ public function handle() } $this->runProcessInBlast($process, true, [ - 'STORYBOOK_SERVER_URL' => $this->storybookServer, + 'STORYBOOK_SERVER_URL' => $serverUrl ?? $this->storybookServer, + 'STORYBOOK_PORT' => $port ?? 6006, 'STORYBOOK_STATUSES' => json_encode($this->storybookStatuses), 'STORYBOOK_THEME' => json_encode($this->storybookTheme), 'STORYBOOK_CUSTOM_THEME' => json_encode($this->customTheme), @@ -131,6 +134,7 @@ public function handle() 'PROJECTPATH' => base_path(), 'COMPONENTPATH' => base_path('resources/views/stories'), 'STORYBOOK_SORT_ORDER' => json_encode($this->storybookSortOrder), + 'STORYBOOK_VIEWPORTS' => false, ]); usleep(250000); From d5ff63386b92adf9777951ad914eb341a1d8d39f Mon Sep 17 00:00:00 2001 From: Tim Brook Date: Thu, 15 Feb 2024 15:00:47 -0600 Subject: [PATCH 2/5] Add option to define chromatic token --- src/Commands/Publish.php | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/Commands/Publish.php b/src/Commands/Publish.php index 02a09c5..7c4692c 100644 --- a/src/Commands/Publish.php +++ b/src/Commands/Publish.php @@ -21,7 +21,8 @@ class Publish extends Command */ protected $signature = 'blast:publish {--install : Force install dependencies} - {--url= : set the server url used to load the stories} + {--t|chromatic-token= : the Chromatic project token. Login to Chromatic to generate one} + {--u|url= : set the server url used to load the stories} {--o|output-dir=storybook-static : Directory where to store built files}'; /** @@ -70,12 +71,14 @@ public function handle() $npmInstall = $this->option('install'); $installMessage = $this->getInstallMessage($npmInstall); $outputDir = $this->option('output-dir'); + $chromaticToken = $this->option('chromatic-token'); if (Str::startsWith($outputDir, '/')) { $outputDir = Str::after($outputDir, '/'); } - $progressBar = $this->output->createProgressBar(3); + $progessBarSteps = $chromaticToken ? 4 : 3; + $progressBar = $this->output->createProgressBar($progessBarSteps); $progressBar->setFormat('%current%/%max% [%bar%] %message%'); $progressBar->setMessage($installMessage); @@ -122,7 +125,8 @@ public function handle() $this->runProcessInBlast($process, true, [ 'STORYBOOK_SERVER_URL' => $serverUrl ?? $this->storybookServer, - 'STORYBOOK_PORT' => $port ?? 6006, + 'STORYBOOK_STATIC_PATH' => public_path(), + 'STORYBOOK_PORT' => 6006, 'STORYBOOK_STATUSES' => json_encode($this->storybookStatuses), 'STORYBOOK_THEME' => json_encode($this->storybookTheme), 'STORYBOOK_CUSTOM_THEME' => json_encode($this->customTheme), @@ -155,6 +159,24 @@ public function handle() $this->CopyDirectory($outputPath, $destPath); + // publish to chromatic + if ($chromaticToken) { + $this->info(''); + $progressBar->setMessage('Publishing to Chromatic'); + $progressBar->advance(); + + $chromaticProcess = [ + 'npx', + 'chromatic', + '--storybook-build-dir', + $destPath, + ]; + + $this->runProcessInBlast($chromaticProcess, true, [ + 'CHROMATIC_PROJECT_TOKEN' => $chromaticToken, + ]); + } + $this->info(''); $progressBar->setMessage('Publish Complete'); $progressBar->finish(); From cfa5bd698b456f62349cef5bb06d5c00bdad27ca Mon Sep 17 00:00:00 2001 From: Tim Brook Date: Wed, 21 Feb 2024 10:41:03 -0600 Subject: [PATCH 3/5] Add option to pass auth credentials in launch and publish tasks --- .gitignore | 1 + .storybook/preview.js | 29 ++++++++++++++++++++++++++++- src/Commands/Launch.php | 2 ++ src/Commands/Publish.php | 2 ++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5f51694..108b516 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ /storybook/node_modules /vendor /tmp +/storybook-static .env !.env.example .phpunit.result.cache diff --git a/.storybook/preview.js b/.storybook/preview.js index b6808b3..9a35c6a 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -14,6 +14,32 @@ let setDocsTheme = (configDocsTheme) => { const customViewports = JSON.parse(process.env.STORYBOOK_VIEWPORTS); +const fetchStoryHtml = async (url, path, params, context) => { + const fetchUrl = new URL(`${url}/${path}`); + fetchUrl.search = new URLSearchParams({ + ...context.globals, + ...params + }).toString(); + + const headers = new Headers(); + + if (process.env.STORYBOOK_SERVER_AUTH) { + headers.append( + 'Authorization', + `Basic ${btoa(process.env.STORYBOOK_SERVER_AUTH)}` + ); + } + + const response = await fetch(fetchUrl, { + method: 'GET', + headers + }); + + const html = await response.text(); + + return html; +}; + const preview = { parameters: { viewport: { @@ -23,7 +49,8 @@ const preview = { expanded: JSON.parse(process.env.STORYBOOK_EXPANDED_CONTROLS) }, server: { - url: process.env.STORYBOOK_SERVER_URL + url: process.env.STORYBOOK_SERVER_URL, + fetchStoryHtml }, layout: 'centered', status: { diff --git a/src/Commands/Launch.php b/src/Commands/Launch.php index d2d6326..219a788 100644 --- a/src/Commands/Launch.php +++ b/src/Commands/Launch.php @@ -46,6 +46,7 @@ public function __construct(Filesystem $filesystem) $this->filesystem = $filesystem; $this->storybookServer = config('blast.storybook_server_url'); + $this->storybookServerAuth = config('blast.storybook_server_auth'); $this->vendorPath = $this->getVendorPath(); $this->storybookStatuses = config('blast.storybook_statuses'); $this->storybookTheme = config('blast.storybook_theme', 'normal'); @@ -132,6 +133,7 @@ public function handle() $this->runProcessInBlast(['npm', 'run', 'storybook'], true, [ 'STORYBOOK_SERVER_URL' => $this->storybookServer, + 'STORYBOOK_SERVER_AUTH' => $this->storybookServerAuth, 'STORYBOOK_STATIC_PATH' => public_path(), 'STORYBOOK_PORT' => $port ?? 6006, 'STORYBOOK_STATUSES' => json_encode($this->storybookStatuses), diff --git a/src/Commands/Publish.php b/src/Commands/Publish.php index 7c4692c..67e4121 100644 --- a/src/Commands/Publish.php +++ b/src/Commands/Publish.php @@ -46,6 +46,7 @@ public function __construct(Filesystem $filesystem) $this->filesystem = $filesystem; $this->storybookServer = config('blast.storybook_server_url'); + $this->storybookServerAuth = config('blast.storybook_server_auth'); $this->vendorPath = $this->getVendorPath(); $this->storybookStatuses = config('blast.storybook_statuses'); $this->storybookTheme = config('blast.storybook_theme', false); @@ -125,6 +126,7 @@ public function handle() $this->runProcessInBlast($process, true, [ 'STORYBOOK_SERVER_URL' => $serverUrl ?? $this->storybookServer, + 'STORYBOOK_SERVER_AUTH' => $this->storybookServerAuth, 'STORYBOOK_STATIC_PATH' => public_path(), 'STORYBOOK_PORT' => 6006, 'STORYBOOK_STATUSES' => json_encode($this->storybookStatuses), From 1ea7943827b1ce2a92b59367492bd2b2676f82c9 Mon Sep 17 00:00:00 2001 From: Tim Brook Date: Mon, 11 Mar 2024 09:44:08 -0500 Subject: [PATCH 4/5] Add chromatic script to stop it prompting to add it after publishing --- package.json | 3 ++- src/Commands/Publish.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 28e3ef3..04dcc88 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "stylelint": "stylelint", "stylelint:all": "stylelint ./resources/**/*.css", "prettier": "prettier", - "prettier:php": "prettier --write -- \"./src/**/*.php\"" + "prettier:php": "prettier --write -- \"./src/**/*.php\"", + "chromatic": "npx chromatic" }, "devDependencies": { "@prettier/plugin-php": "^0.22.2", diff --git a/src/Commands/Publish.php b/src/Commands/Publish.php index 67e4121..4618143 100644 --- a/src/Commands/Publish.php +++ b/src/Commands/Publish.php @@ -168,7 +168,8 @@ public function handle() $progressBar->advance(); $chromaticProcess = [ - 'npx', + 'npm', + 'run', 'chromatic', '--storybook-build-dir', $destPath, From 6dbf50e4c7aadb937777262ae6e5ab742228aaba Mon Sep 17 00:00:00 2001 From: Tim Brook Date: Thu, 4 Apr 2024 16:54:27 -0500 Subject: [PATCH 5/5] Update docs --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d7faa74..4a58ef1 100644 --- a/README.md +++ b/README.md @@ -521,6 +521,8 @@ Blast can build a static Storybook app and publish it to your public folder. You php artisan blast:publish ``` +You can also publish to Chromatic using the `-t` or `--chromatic-token` option and your Chromatic project token. Note that it requires the `-u` or `--url` option to also be defined as a publicly accessible url as Storybook Server will use that to render the components in Chromatic. + ## Generate Tailwind Documenatation Stories Blast can automatically generate stories to visualize your Tailwind configuration. See 'auto_documentation' above to see how to configure which stories to generate.