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/main.js b/.storybook/main.js index 591f413..0b02ad9 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -23,4 +23,8 @@ const config = { } }; +if (process.env.STORYBOOK_STATIC_PATH) { + config.staticDirs = [process.env.STORYBOOK_STATIC_PATH]; +} + export default config; 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/.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/README.md b/README.md index 706ecd8..873ff3f 100644 --- a/README.md +++ b/README.md @@ -527,6 +527,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. diff --git a/package-lock.json b/package-lock.json index 4e5e515..866a91b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6833,9 +6833,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "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", @@ -7217,9 +7217,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.26", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.26.tgz", + "integrity": "sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw==", "funding": [ { "type": "opencollective", @@ -7235,7 +7235,7 @@ } ], "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, diff --git a/package.json b/package.json index f36f662..9927b59 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/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/public/main.css b/public/main.css index fbce3f6..0b17602 100644 --- a/public/main.css +++ b/public/main.css @@ -332,8 +332,15 @@ text-align: left; } .blast-font-mono { - font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, - Liberation Mono, Courier New, monospace; + font-family: + ui-monospace, + SFMono-Regular, + Menlo, + Monaco, + Consolas, + Liberation Mono, + Courier New, + monospace; } .blast-text-2xl { font-size: 1.5rem; @@ -388,9 +395,21 @@ .blast-wysiwyg, .blast-wysiwyg h1, .blast-wysiwyg h2 { - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, - Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, - Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + Segoe UI, + Roboto, + Helvetica Neue, + Arial, + Noto Sans, + sans-serif, + Apple Color Emoji, + Segoe UI Emoji, + Segoe UI Symbol, + Noto Color Emoji; } .blast-wysiwyg h1, .blast-wysiwyg h2 { @@ -415,9 +434,21 @@ } .blast-wysiwyg h3 { margin-top: 1.5rem; - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, - Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, - Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + Segoe UI, + Roboto, + Helvetica Neue, + Arial, + Noto Sans, + sans-serif, + Apple Color Emoji, + Segoe UI Emoji, + Segoe UI Symbol, + Noto Color Emoji; font-size: 1.5rem; line-height: 2rem; font-weight: 600; @@ -438,9 +469,21 @@ .blast-wysiwyg h5, .blast-wysiwyg h6 { margin-top: 1.5rem; - font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, - Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, - Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; + font-family: + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + Segoe UI, + Roboto, + Helvetica Neue, + Arial, + Noto Sans, + sans-serif, + Apple Color Emoji, + Segoe UI Emoji, + Segoe UI Symbol, + Noto Color Emoji; font-size: 1.25rem; line-height: 1.75rem; font-weight: 600; diff --git a/src/Commands/Launch.php b/src/Commands/Launch.php index fe1de58..ccf3c1a 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 306e8c7..0cba1fb 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}'; /** @@ -45,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); @@ -70,12 +72,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); @@ -129,6 +133,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), @@ -163,6 +168,25 @@ public function handle() $this->CopyDirectory($outputPath, $destPath); + // publish to chromatic + if ($chromaticToken) { + $this->info(''); + $progressBar->setMessage('Publishing to Chromatic'); + $progressBar->advance(); + + $chromaticProcess = [ + 'npm', + 'run', + 'chromatic', + '--storybook-build-dir', + $destPath, + ]; + + $this->runProcessInBlast($chromaticProcess, true, [ + 'CHROMATIC_PROJECT_TOKEN' => $chromaticToken, + ]); + } + $this->info(''); $progressBar->setMessage('Publish Complete'); $progressBar->finish();