Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ The route Storybook Server uses to render components. You shouldn't need to chan

Default: `config('app.url') . '/storybook_preview'`

#### `storybook_addons`

An array of custom [storybook addons](https://storybook.js.org/integrations/) you'd like to use in your project. Note that not all addons are compatible with Storybook Server. Read about how to configure addons in your stories in the Storybook Configuration section below.

Default: `[]`

#### `auto_documentation`

Blast can automatically generate documentation pages in the form of stories based on your Tailwind config. Use this array to specify which documentation pages to generate. All options are loaded by default.
Expand Down Expand Up @@ -337,7 +343,12 @@ There are certain Storybook elements you can configure from within your story bl
],
'actions' => [
'handles' => ['mouseover', 'click']
]
],
'addons' => [
'jira' => [
'id' => 'ABC-123'
]
],
])
```

Expand All @@ -352,6 +363,7 @@ The supported options for this directive are:
- `args` - an array of static data used to create storybook fields. You can read more about that [here](https://github.com/storybookjs/storybook/tree/main/app/server#server-rendering). The keys in the array are passed to the blade view and updated when the fields are updated in storybook.
- `argTypes` - an array to define the args used for the controls. You can read more about them [here](https://storybook.js.org/docs/react/api/argtypes)
- `actions.handles` - an array defining the events that are passed to the `@storybook-actions` addon. You can read more about actions [here](https://storybook.js.org/docs/react/essentials/actions) - See the Action Event Handlers heading.
- `addons` - an array to define options for any custom addons. Any options defined here are added to the parameters array in the story. Some addons require you to modify storybook config files which can be done by publishing them to your project directory.

## Customizing the story view

Expand Down
2 changes: 2 additions & 0 deletions config/blast.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
'storybook_server_url' =>
env('STORYBOOK_SERVER_HOST', env('APP_URL')) . '/storybook_preview',

'storybook_addons' => [],

/**
* Specify which documentation pages to generate for the Tailwind classes used in your application
* Defaults to `[]` which will render all
Expand Down
6 changes: 6 additions & 0 deletions src/Commands/GenerateStories.php
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,12 @@ private function buildChildTemplate($item)
];
}
}

if (Arr::has($options, 'addons')) {
foreach ($options['addons'] as $key => $addon) {
$data['parameters'][$key] = $addon;
}
}
}

$data['hash'] = $this->getBladeChecksum(
Expand Down
90 changes: 85 additions & 5 deletions src/Traits/Helpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ private function installDependencies($npmInstall)
$updateStorybook = $this->checkStorybookVersions(
$this->storybookInstallVersion,
);
$updateAddons = true;

if ($npmInstall || (!$npmInstall && !$depsInstalled)) {
$this->runProcessInBlast(
Expand All @@ -113,7 +114,13 @@ private function installDependencies($npmInstall)
);

$this->installStorybook($this->storybookInstallVersion);

$this->installAddons();
} else {
if ($updateAddons) {
$this->installAddons();
}

if ($updateStorybook) {
$this->installStorybook($this->storybookInstallVersion);
}
Expand Down Expand Up @@ -186,20 +193,20 @@ private function installStorybook($storybookVersion)
}
}

private function getInstalledStorybookVersion()
private function getInstalledPackageVersion($package)
{
$version = false;
$rawOutput = $this->runProcessInBlast(
['npm', 'list', 'storybook', '--json'],
['npm', 'list', $package, '--json'],
false,
null,
false,
true,
);
$data = json_decode($rawOutput, true);

if (isset($data['dependencies']['storybook'])) {
$version = $data['dependencies']['storybook']['version'];
if (isset($data['dependencies'][$package])) {
$version = $data['dependencies'][$package]['version'];
}

return $version;
Expand All @@ -208,7 +215,9 @@ private function getInstalledStorybookVersion()
private function checkStorybookVersions($storybookVersion)
{
// check if version matches installed version
$installedStorybookVersion = $this->getInstalledStorybookVersion();
$installedStorybookVersion = $this->getInstalledPackageVersion(
'storybook',
);

if ($installedStorybookVersion !== $this->storybookInstallVersion) {
$this->newLine();
Expand All @@ -221,4 +230,75 @@ private function checkStorybookVersions($storybookVersion)

return false;
}

private function storybookConfigPublished()
{
$projectMainConfigPath = base_path('.storybook/main.js');

return $this->filesystem->exists($projectMainConfigPath);
}

private function storybookConfigPath($path = false)
{
$configPublished = $this->storybookConfigPublished();
$configPath = $configPublished
? base_path('.storybook')
: $this->vendorPath . '/.storybook';

if ($path) {
$path = Str::start($path, '/');
}
return Str::of($configPath)->finish($path);
}

private function installAddons()
{
$storybookConfigPublished = $this->storybookConfigPublished();
$mainJsPath = $this->storybookConfigPath('main.js');
$mainJsContents = $this->filesystem->get($mainJsPath);
$addons = config('blast.storybook_addons');
$installedAddons = [];

if (!$addons) {
return 0;
}

$this->newLine();
foreach ($addons as $addon) {
$this->info('Found custom addon - ' . $addon);

$addonInstalled = $this->getInstalledPackageVersion($addon);

if (!$addonInstalled) {
$this->info('Installing ' . $addon);

$this->runProcessInBlast(['npm', 'install', $addon]);
} else {
$this->info('Addon already installed. Skipping installation.');
}

if (!Str::contains($mainJsContents, $addon)) {
$this->info('Addon missing from .storybook/main.js. Adding.');

$addonName = Str::of($addon);
if ($storybookConfigPublished) {
$addonName = $addonName->start(
'../vendor/area17/blast/node_modules/',
);
}

$installedAddons[] = $addonName->start("'")->finish("'");
}
}

if (filled($installedAddons)) {
$this->filesystem->replaceInFile(
'addons: [',
"addons: [\n" . implode(",\n", $installedAddons) . ',',
$mainJsPath,
);
}

$this->info('Addons installed');
}
}