Storybook for Laravel Blade 🚀

Overview

Blast — Storybook for Laravel Blade 🚀

What is Blast?

Blast is a low maintenance component library using Storybook Server, built to integrate into your Laravel apps.

Blast allows you to render examples of your app's components using the blade templating engine using Storybook Server within your Laravel app.

Install

composer require area17/blast

You may need to configure your app's assets in config/blast.php after install. To publish the configuration file, use:

php artisan vendor:publish --provider="A17\Blast\BlastServiceProvider" --tag="blast-config"

Start Storybook

From your app's root directory run:

php artisan blast:launch

This will install all of the dependencies, generate stories and start a Storybook instance, as well as a watch task so updates to .md and .blade.php files in resources/views/stories and .php files in resources/views/stories/data will automatically regenerate the stories and update Storybook.

Options

  • --noInstall - skip installing dependencies
  • --noGenerate - skip auto-generating stories based on existing components

Generating Stories

Blast can also generate stories outside of the launch task. You can do this by running:

php artisan blast:generate-stories

Options

  • --watch - watches the story blade files and updates stories

Storybook Configuration

Global configuration can be done through the config/blast.php.

Options

storybook_server_url

The route Storybook Server uses to render components. You shouldn't need to change this as it isn't ever visible on the FE.

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

storybook_theme

The array of theme options used by Storybook. More info here.

Default: []

canvas_bg_color

Set the background color of the component canvas area. The Storybook theme doesn't allow this without also changing the background of other areas of the UI.

Default: ''

assets

An array of urls to the css and js used by your components. The css and js urls are seperated out as the css is included in the head and the js is included before the closing body tag. You will most likely need to configure this after installing the package.

Default: [ 'css' => [], 'js' => [], ]

storybook_statuses

Blast ships with the Status Addon by Etch. This allows you to add custom status indicators to each component. This option allows you to customise these status indicators. More information on this can be found in the Custom Status section below.

Default:

[
    'deprecated' => [
        'background' => '#e02929',
        'color' => '#ffffff',
        'description' =>
            'This component is deprecated and should no longer be used',
    ],
    'wip' => [
        'background' => '#f59506',
        'color' => '#ffffff',
        'description' => 'This component is a work in progress',
    ],
    'readyForQA' => [
        'background' => '#34aae5',
        'color' => '#ffffff',
        'description' => 'This component is complete and ready to qa',
    ],
    'stable' => [
        'background' => '#1bbb3f',
        'color' => '#ffffff',
        'description' => 'This component is stable and released',
    ],
]

build_timeout

Set a custom timeout for tasks in launch and generate-stories

Default: 300

vendor_path

The relative path to the Blast package directory

Default: vendor/area17/blast

components

An array of custom components used by Blast.

Default: [ 'docs-page' => Components\DocsPages\DocsPage::class ]

Story Configuration

There are certain Storybook elements you can configure from within your story blade files. You can do this by adding the @storybook directive to the top of your files:

@storybook([
    'preset' => 'file.option'
    'name' => 'Component Name',
    'layout' => 'fullscreen',
    'status' => 'stable',
    'design' => "https://www.figma.com/file/LKQ4FJ4bTn\CSjedbRpk931/Sample-File",
    'args' => [
        'label' => 'Lorem Ipsum',
        'icon' => 'lorem-icon-dolor'
    ],
    'argTypes' => [
        'icon' =>[
            'options' => [
                'lorem-icon-dolor', 'another-icon'
            ],
            'control' => [
                'type' => 'select'
            ]
        ]
    ]
])

The supported options for this directive are:

  • preset - Use a preset as the base for the component story. Setting options in this directive will override the preset
  • name - Overrides the auto generated name in the Storybook sidebar.
  • layout - Set the component layout in canvas area. Options are fullscreen, padded, centered (default).
  • status - adds a status badge to the component story. Can be configured in the package config. See below for more info.
  • design - a Figma url for the component
  • args - an array of static data used to create storybook fields. You can read more about that here. 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

Demo Components

Running php artisan blast:demo will create all the files needed to display a demo component. It creates files in your resources/views/components and resources/views/stories directories and generates the stories.

It can be run alongside the php artisan blast:launch task or you can run the demo task and then the launch task after to init Storybook.

Presetting story options

You can create preset options for components to reuse throughtout your storybook instance.

The preset options use the same structure as Laravel config files:

return [
    'primary' => [
        'args' => [
            'href' => '#',
            'label' => 'Primary',
        ],
    ],
    'primaryIcon' => [
        'args' => [
            'label' => 'Primary',
            'icon' => 'search-24',
            'iconPosition' => 'after',
        ],
        'argTypes' => [
            'icon' => [
                'control' => 'select',
                'options' => ['search-24', 'chevron-right-24', 'external-24'],
            ],
            'iconPosition' => [
                'control' => 'radio',
                'options' => ['Before' => 'before', 'After' => 'after'],
            ],
        ],
    ],
];

You can preset any of the options available in the @storybook directive.

To use the preset, set the preset option to the array path (using "dot" notation) where the first part is the name of the file followed by the option you wish to access.

@storybook([
    'preset' => 'button.primary',
    'args' => [
        'label' => 'Read More',
    ],
]);

In this example it would update the label from 'Primary' to 'Read More'.

Presetting data

In some instances it is beneficial to reuse data from other components in a new component. For example, a post list may use data for multiple post components.

To do this, you can reference the data in your new component's data file in a similar way to how you would set the preset in your story.

Use the presetArgs key to define the args with which you would like to data from another component. You can set the presets to either an array of references, or a single reference.

The example below creates the items array used in a card-list component using data from the card stories.

// stories/data/card.php
return [
    'post' => [
        'args' => [
            'href' => '#',
            'title' => 'Euismod Vulputate',
            'subtitle' => 'Purus Malesuada',
            'description' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id ligula porta felis euismod semper.'
        ]
    ],
    'post_alt' => [
        'args' => [
            'href' => '#',
            'title' => 'Cursus Aenean Quam',
            'subtitle' => 'Pharetra Quam',
            'description' => 'Etiam porta sem malesuada magna mollis euismod.',
        ]
    ],
    'post_alt_2' => [
        'args' => [
            'href' => '#',
            'title' => 'Etiam Cras Euismod',
            'subtitle' => 'Risus Etiam Pharetra Fusce',
            'description' => 'Maecenas faucibus mollis interdum. Vestibulum id ligula porta felis euismod semper.',
        ]
    ]
];

// stories/data/card-list.php
return [
    'posts' => [
        'presetArgs' => [
            'items' => [
                'card.post_alt_2',
                'card.post_alt',
                'card.post'
            ]
        ]
    ]
];

// output stories.json
"args": {
    "items": [
        {
            "href": "#",
            "title": "Etiam Cras Euismod",
            "subtitle": "Risus Etiam Pharetra Fusce",
            "description": "Maecenas faucibus mollis interdum. Vestibulum id ligula porta felis euismod semper."
        },
        {
            "href": "#",
            "title": "Cursus Aenean Quam",
            "subtitle": "Pharetra Quam",
            "description": "Etiam porta sem malesuada magna mollis euismod."
        },
        {
            "href": "#",
            "title": "Euismod Vulputate",
            "subtitle": "Purus Malesuada",
            "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id ligula porta felis euismod semper."
        }
    ]
},

Custom Status

Blast comes with 4 preset statuses to use in your stories - deprecated, wip, readyForQA and stable. You can define custom statuses in config/blast.php by passing and array of statuses the storybook_statuses config. For example:

'storybook_statuses' => [
    "phase1" => [
      "background" => '#333333',
      "color" => '#ffffff',
      "description" => 'This component is part of phase 1',
    ]
]

More infomation on this addon can be found here.

Note: Defining custom statuses will override the existing statuses.

Documentation

Adding a README.md to your storybook blade directory will allow you to add notes to the Docs tab for each component in Storybook. The content of the markdown file will be output above the auto-generated Storybook content.

Troubleshooting

If you see a Failed to fetch message when viewing your stories you will need to go to the path that Storybook is trying to load (open dev tools > network and right click the failed path and open in a new tab) and debug there. Any php errors or dd will trigger the Failed to fetch message.

Known Issues

  • Renaming the story blade files can sometimes result in the story for that component being duplicated. You can work around this by running php artisan blast:generate-stories
Comments
  • CORS error thrown line 46 render.js

    CORS error thrown line 46 render.js

    Hi Folks, Please let me know if you need more info than I provide: I have tried this package with 2 laravel 8 apps. One on a vagrant/homestead installation on windows and one on a wampserver installation on windows. I have read and re-read the docs re package installation. Both time keep getting CORS error thrown from the iFrame within blast page. I have debugged through the JS to line 46 in render.js where the error gets throws. I have tried disabling CORS protection in laravel by commenting CORS line in App\HTTP\Kernal.php, I have also tried adding custom CORS class to laravel to allow all.

    I have also debugged through the php call stack - am I correct in thinking you cannot use the url generated in blast.php to access the page as it doesn't contain the necessary parameters e.g. myapp.local/storybook_preview/{because this bit is missing which access the template directory}. I am thinking you have coded this to be NOT accessed in this way but rather through the automated page loading from the 'artisan blast:launch' command with the localhost:6006 url? Therefore, I am starting to think along the lines of Laravel getting it's knickers in a twist over port 6006? or localhost having a fit over who is listening to what?

    It is worth noting that I have noticed that the artisan command will boot the storybook server without a webserver running at all and open the browser window (Chrome) with the same errorbut the rest of the page loading ok. Help resolving this issue would be amazing please as I am looking forward to trying out this package. The only component within the stories directory is the demo one from this package. Cheers, Rob.

    STACK TRACE FROM DEV CONSOLE: DevTools failed to load source map: Could not load content for http://localhost:6006/index.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE DevTools failed to load source map: Could not load content for http://localhost:6006/react-popper-tooltip.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE iframe.html:1 Access to fetch at 'http://moneyscout.local/storybook_preview/blast-demo/button?measureEnabled=false&outline=false&label=Button&href=http%3A%2F%2Farea17.com&icon=plus-24&iconPosition=after' from origin 'http://localhost:6006' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. render.js:46 GET http://moneyscout.local/storybook_preview/blast-demo/button?measureEnabled=false&outline=false&label=Button&href=http%3A%2F%2Farea17.com&icon=plus-24&iconPosition=after net::ERR_FAILED 200 _callee$ @ render.js:46 tryCatch @ runtime.js:63 invoke @ runtime.js:294 (anonymous) @ runtime.js:119 asyncGeneratorStep @ render.js:7 _next @ render.js:9 (anonymous) @ render.js:9 (anonymous) @ render.js:9 defaultFetchStoryHtml @ render.js:61 _callee2$ @ render.js:118 tryCatch @ runtime.js:63 invoke @ runtime.js:294 (anonymous) @ runtime.js:119 asyncGeneratorStep @ render.js:7 _next @ render.js:9 (anonymous) @ render.js:9 (anonymous) @ render.js:9 _renderMain @ render.js:167 renderMain @ render.js:99 _callee3$ @ StoryRenderer.js:388 tryCatch @ runtime.js:63 invoke @ runtime.js:294 (anonymous) @ runtime.js:119 asyncGeneratorStep @ StoryRenderer.js:18 _next @ StoryRenderer.js:20 Promise.then (async) asyncGeneratorStep @ StoryRenderer.js:18 _next @ StoryRenderer.js:20 (anonymous) @ StoryRenderer.js:20 (anonymous) @ StoryRenderer.js:20 renderStory @ StoryRenderer.js:429 _callee2$ @ StoryRenderer.js:266 tryCatch @ runtime.js:63 invoke @ runtime.js:294 (anonymous) @ runtime.js:119 asyncGeneratorStep @ StoryRenderer.js:18 _next @ StoryRenderer.js:20 (anonymous) @ StoryRenderer.js:20 (anonymous) @ StoryRenderer.js:20 renderStoryIfChanged @ StoryRenderer.js:290 _callee$ @ StoryRenderer.js:160 tryCatch @ runtime.js:63 invoke @ runtime.js:294 (anonymous) @ runtime.js:119 asyncGeneratorStep @ StoryRenderer.js:18 _next @ StoryRenderer.js:20 (anonymous) @ StoryRenderer.js:20 (anonymous) @ StoryRenderer.js:20 renderCurrentStory @ StoryRenderer.js:174 (anonymous) @ StoryRenderer.js:87 (anonymous) @ index.js:168 handleEvent @ index.js:167 handler @ index.js:93 emit @ index.js:100 setSelection @ story_store.js:961 finishConfiguring @ story_store.js:424 ConfigApi.configure @ config_api.js:26 (anonymous) @ loadCsf.js:223 configure @ index.js:17 ./.storybook/generated-stories-entry.js @ generated-stories-entry.js:6 webpack_require @ bootstrap:24 webpack_exec @ util.inspect:1 (anonymous) @ util.inspect:1 webpack_require.O @ chunk loaded:23 (anonymous) @ util.inspect:1 webpackJsonpCallback @ jsonp chunk loading:558 (anonymous) @ main.iframe.bundle.js:1 Show 36 more frames index.js:56 TypeError: Failed to fetch at _callee$ (render.js:46) at tryCatch (runtime.js:63) at Generator.invoke [as _invoke] (runtime.js:294) at Generator.next (runtime.js:119) at asyncGeneratorStep (render.js:7) at _next (render.js:9) at render.js:9 at new Promise () at render.js:9 at defaultFetchStoryHtml (render.js:61)

    VAR DUMP of fetchUrl - passed into fetch(fetchURL) at which point the error is thrown: fetchUrl: URL hash: "" host: "moneyscout.local" hostname: "moneyscout.local" href: "http://moneyscout.local/storybook_preview/blast-demo/button?measureEnabled=false&outline=false&label=Button&href=http%3A%2F%2Farea17.com&icon=plus-24&iconPosition=after" origin: "http://moneyscout.local" password: "" pathname: "/storybook_preview/blast-demo/button" port: "" protocol: "http:" search: "?measureEnabled=false&outline=false&label=Button&href=http%3A%2F%2Farea17.com&icon=plus-24&iconPosition=after" searchParams: URLSearchParams {} username: ""

    COMPOSER.JSON: { "name": "laravel/laravel", "type": "project", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "require": { "php": "^7.3|^8.0", "area17/blast": "^1.2", "fruitcake/laravel-cors": "^2.0", "guzzlehttp/guzzle": "^7.0.1", "laravel/framework": "^8.54", "laravel/sanctum": "^2.11", "laravel/tinker": "^2.5", "laravel/ui": "^3.3", "livewire/livewire": "^2.6", "silviolleite/laravelpwa": "^2.0" }, "require-dev": { "facade/ignition": "^2.5", "fakerphp/faker": "^1.9.1", "laravel/sail": "^1.0.1", "mockery/mockery": "^1.4.2", "nunomaduro/collision": "^5.0", "phpunit/phpunit": "^9.3.3" }, "autoload": { "psr-4": { "App\": "app/", "Database\Factories\": "database/factories/", "Database\Seeders\": "database/seeders/" } }, "autoload-dev": { "psr-4": { "Tests\": "tests/" } }, "scripts": { "post-autoload-dump": [ "Illuminate\Foundation\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi" ], "post-update-cmd": [ "@php artisan vendor:publish --tag=laravel-assets --ansi" ], "post-root-package-install": [ "@php -r "file_exists('.env') || copy('.env.example', '.env');"" ], "post-create-project-cmd": [ "@php artisan key:generate --ansi" ] }, "extra": { "laravel": { "dont-discover": [] } }, "config": { "optimize-autoloader": true, "preferred-install": "dist", "sort-packages": true }, "minimum-stability": "dev", "prefer-stable": true }

    PACKAGE.JSON: { "private": true, "scripts": { "dev": "npm run development", "development": "mix", "watch": "mix watch", "watch-poll": "mix watch -- --watch-options-poll=1000", "hot": "mix watch --hot", "prod": "npm run production", "production": "mix --production" }, "devDependencies": { "axios": "^0.21", "bootstrap": "^4.6.0", "jquery": "^3.6", "laravel-mix": "^6.0.6", "lodash": "^4.17.19", "popper.js": "^1.16.1", "postcss": "^8.1.14", "resolve-url-loader": "^3.1.2", "sass": "^1.32.11", "sass-loader": "^11.0.1" }, "dependencies": { } Capture

    }

    opened by RobertAByrnes 7
  • Addition of source code to Docs tab in Blast view

    Addition of source code to Docs tab in Blast view

    @mrtimbrook Will do, I had a dive into the Storybook docs about this topic earlier,. Will do more digging. Looks like the dependency is already there.

    opened by RobertAByrnes 6
  • Feature/add themes and desc

    Feature/add themes and desc

    I've opened this pull request to add the ability to change theme from blast.php between default(light) and dark theme for both the canvas and docs pages. Also included within the PR is the ability to define a custom theme from blast.php

    Another addition is to enable expanded documentation in the controls tab via a bool in blast.php. To render the description add 'description' to argTypes within @storybook blade directive, e.g.

    @storybook([
        'name' => 'Theme Toggle',
        'status' => 'readyForQA',
        'design' => "",
        'args' => [
            'label' => 'Theme',
            'color' => 'text-muted'
        ],
        'argTypes' => [
            'label' => [
                'options' => [
                    'Theme', 'Color Theme', 'Colour Theme', 'Dark Mode' 
                ],
                'control' => [
                    'type' => 'select'
                ],
                'description' => 'label to the right of the toggle switch',
                'defaultValue' => 'Theme',
                'table' => [
                    'type' => [
                        'summary' => 'string'
                    ],
                    'defaultValue' => [
                        'summary' => 'Theme'
                    ],
                ],
            ],
            'color' =>[
                'options' => [
                    'text-light', 'text-primary', 'text-dark', 'text-dark'
                ],
                'control' => [
                    'type' => 'select'
            ],
            'description' => 'bootstrap 5 classes for text-color',
            'defaultValue' => 'text-muted',
            'table' => [
                'type' => [
                    'summary' => 'string'
                ],
                'defaultValue' => [
                    'summary' => 'text-muted'
                ],
            ],
            ]
        ]
    ])
    

    Storybook_custom_theme_docs_page Storybook_custom_theme_expanded_controls Storybook_dark_expanded_controls

    opened by RobertByrnes 5
  • Feature/add preview head.html

    Feature/add preview head.html

    This PR includes a workaround for CORS errors generated by locally serving assets which require access to folders nested inside /public - I think allowing CORS from the laravel side is half the issue and resolvable, however storybook.js itself will need to add Access-Control-Allow-Headers in order for a soultion to ALL CORS errors. This PR allows the creation of preview-head.html inside /vendor/.storybook/ which storybook uses to serve assets, CDN's may be used for storybook assets causing CORS errors, without affecting how assets are served in the application. The main code additions here are to BlastServiceProvider.php to get the assets from blast.php and check against mix-manifest.json to decide what to serve and where.

    external_links & external_scripts

    Assets causing CORS errors (due to attempting to access public/folder_name from localhost without Access-Control-Allow-Headers) may be placed in the external_links / external_scripts array below instead using a CDN.

    • Links - ['link' => 'rel', 'link' => 'rel'] e.g. 'https://unpkg.com/[email protected]/css/boxicons.min.css' => 'stylesheet'
    • Scripts - ['src', 'src'] e.g. 'https://code.jquery.com/jquery-3.6.0.min.js'

    When these arrays are populated and assets are being autoloaded via mix-manifest.json, blast will use regex to identify these links and refrain from serving them locally using the CDN instead to avoid generating CORS errors from the storybook url. More can be read on adding assets to the storybook preview-head.html here.

    opened by RobertByrnes 3
  • Ability to pass args to story as an array?

    Ability to pass args to story as an array?

    Hi @mrtimbrook is this supported and I am missing something? I have been so far able to pass an array to the story so it registers in the controls addon effectively but only gets passed to the components blade as a bool?

    opened by RobertByrnes 2
  • Bugfix/terminate script for homestead users

    Bugfix/terminate script for homestead users

    Ref issue #27 Add a check to installing dependencies for Laravel Homestead users on windows platform to avoid waiting for and figuring out installation issues. Issues are caused by default behaviour of windows not allowing the creation of symbolic links.

    opened by RobertByrnes 2
  • Webpack update not working with Sail Laravel

    Webpack update not working with Sail Laravel

    I use Laravel Sail to run my project locally. Initial launch with blast:launch works fine, but as soon as some code is changed the node process throws an error.

    [1] /var/www/html/vendor/area17/blast/node_modules/chokidar-cli/utils.js:16
    [1]         throw new Error('$SHELL environment variable is not set.');
    [1]               ^
    [1] 
    [1] Error: $SHELL environment variable is not set.
    [1]     at Object.run (/var/www/html/vendor/area17/blast/node_modules/chokidar-cli/utils.js:16:15)
    [1]     at run (/var/www/html/vendor/area17/blast/node_modules/chokidar-cli/index.js:225:18)
    [1]     at FSWatcher.<anonymous> (/var/www/html/vendor/area17/blast/node_modules/chokidar-cli/index.js:164:13)
    [1]     at FSWatcher.emit (node:events:378:20)
    [1]     at FSWatcher.emitWithAll (/var/www/html/vendor/area17/blast/node_modules/chokidar-cli/node_modules/chokidar/index.js:541:32)
    [1]     at FSWatcher._emit (/var/www/html/vendor/area17/blast/node_modules/chokidar-cli/node_modules/chokidar/index.js:632:8)
    [1]     at listener (/var/www/html/vendor/area17/blast/node_modules/chokidar-cli/node_modules/chokidar/lib/nodefs-handler.js:370:20)
    [1] npm ERR! code 1
    [1] npm ERR! path /var/www/html/vendor/area17/blast
    [1] npm ERR! command failed
    [1] npm ERR! command sh -c chokidar "$COMPONENTPATH/**/*.blade.php" -d 0 -c "cd $PROJECTPATH && php artisan blast:generate-stories --watchEvent={event} -- '{path}';"
    [1] 
    npm ERR! A complete log of this run can be found in:
    [1] npm ERR!     /home/sail/.npm/_logs/2021-11-09T14_02_55_395Z-debug.log
    [1] npm run watch-components exited with code 1
    

    Looks like chokidar is exiting because env var $SHELL is not present. I echoed $SHELL in the Sail shell, and its defined as /bin/bash.

    opened by wireless25 2
  • Implement Automatic UI Docs for Tailwind Config

    Implement Automatic UI Docs for Tailwind Config

    Work in progress

    The Plan

    Add a task to parse the tailwind config and automatically generate stories for each section of the tailwind docs (color, typography, grid, etc). Build in a way to add support for other UI frameworks in the future?

    Users should be able to:

    • ~~enable/disable the auto-documentation~~ No longer required - will be handled by a dedicated task.
    • ✅ ~~specify the tailwind config path~~
    • ✅ ~~specify which pieces of documentation they would like to render~~
    • ✅ ~~Use the UI Docs components in the app's own stories to create more curated documentation, for example, using the colors UI component in a docs-page component~~

    In Progress

    Added

    • Added a task to parse the tailwind config into a php file.
    • Added a UiDataStore to store the data in the same way as the DataStore and the UI Docs components can then read from this to generate the documentation.
    • Added a colors component to render the colors information

    Todo:

    • ~~Update task to automatically generate the stories.json files~~ No longer required - will be handled blast:generate-stories task
    • ~~Add enable/disable to config/blast.php~~ No longer required - will be handled by a dedicated task.
    • ✅ ~~Add tailwind config path to config/blast.php~~
    • ✅ ~~Add ability to select areas to auto-document to config/blast.php~~
    • ✅ ~~Build out other components~~
    • Add support for colors defined as CSS variables (as used in A17 Tailwind Plugins)
    opened by mrtimbrook 2
  • Make storybook directive parsing more consistent with regular blade statements

    Make storybook directive parsing more consistent with regular blade statements

    First of all, thank you for this package and the accompanying article 🙌 . We are looking into potentially using this in our projects.

    One thing I noticed is that I could not use @storybook (['....']) (notice the whitespace). This PR makes it more consistent with how Laravel parses such statements. I had to check, but yes, in fact Laravel does allow the statement below, not just zero or one spaces 😅; this change is straight from their parser.

    @foreach         (...)
        ...
    @endforeach
    
    opened by koenvu 1
  • EventSource's response has a MIME type (

    EventSource's response has a MIME type ("application/json") that is not "text/event-stream". Aborting the connection.

    I followed the instruction to create a demo from here https://dev.to/area17/getting-started-with-blast-storybook-for-laravel-blade-c5c , After running php artisan blast:demo then php artisan blast:launch , the demo button is not rendered Screenshot 2022-08-15 174712

    checked the console and got this error :

    EventSource's response has a MIME type ("application/json") that is not "text/event-stream". Aborting the connection.
    
    opened by AlaaElden98 1
  • Fix deprecation notice in PHP 8.1

    Fix deprecation notice in PHP 8.1

    This PR fixes a deprecation notice in PHP 8.1 caused by calling a trait's static method directly.

    Details regarding the issue can be found in #52

    With this change the original trait will be marked as deprecated and will delegate the call to a new class. This prevents a BC break and gives developers time to migrate to using this class instead.

    opened by RVxLab 1
  • Bump decode-uri-component from 0.2.0 to 0.2.2

    Bump decode-uri-component from 0.2.0 to 0.2.2

    Bumps decode-uri-component from 0.2.0 to 0.2.2.

    Release notes

    Sourced from decode-uri-component's releases.

    v0.2.2

    • Prevent overwriting previously decoded tokens 980e0bf

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.1...v0.2.2

    v0.2.1

    • Switch to GitHub workflows 76abc93
    • Fix issue where decode throws - fixes #6 746ca5d
    • Update license (#1) 486d7e2
    • Tidelift tasks a650457
    • Meta tweaks 66e1c28

    https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.1

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • [FEATURE-REQUEST] A static solution

    [FEATURE-REQUEST] A static solution

    I am thinking of a solution that avoids running a separate php server for the components, this could make it possible to serve the storybook on a github page.

    Maybe we can just run php in the browser (via a wasm package?)

    Or other ideas?

    opened by conradkirschner 1
  • Error when running Blast with Invoker

    Error when running Blast with Invoker

    I just tried out Beyond Code's Invoker app and upon launch, I got an error that seemed to be related to this package. So I figured I'd cross-post this issue here too:

    https://github.com/beyondcode/invoker-community/issues/318


    OS: darwin Invoker Version: 2.10.0 Laravel Version: 9.34.0 Local project: true PHP Binary: /opt/homebrew/bin/php Route: /project/placeholder?project=local-jNgTuLwmLanmNUq8TaxKzz

    Error:

    ErrorException 
    
      mkdir(): Read-only file system
    
      at /Users/nathan/Code/pigworks/vendor/laravel/framework/src/Illuminate/Filesystem/Filesystem.php:631
        627â–•         if ($force) {
        628â–•             return @mkdir($path, $mode, $recursive);
        629â–•         }
        630â–• 
      ➜ 631▕         return mkdir($path, $mode, $recursive);
        632â–•     }
        633â–• 
        634â–•     /**
        635â–•      * Move a directory.
    
          +3 vendor frames 
      4   [internal]:0
          A17\Blast\DataStore::__construct(Object(Illuminate\Filesystem\Filesystem))
    
          +19 vendor frames 
      24  phar:/Applications/Invoker.app/Contents/Resources/invoker.phar/src/Actions/GetCommandsAction.php:22
          Illuminate\Foundation\Console\Kernel::all()
    

    This happens as soon as I open this particular project. I'm not sure what directory is failing to create. Does Invoker create a file or directory per project?

    As soon as I removed this package, the project opens in Invoker without error. I wasn't really sure how to parse this. Any ideas what might be going on?

    opened by nathangross 1
  • Script asset type

    Script asset type

    I would like to use the same app.js (with my Vue setup) in Blast as in my project (with Vite), but when I add app.js to the config, it doesn't work because the type of the <script> is text/javascript instead of module.

    opened by Thomva 1
  • blast:launch fails on fresh install 1.6

    blast:launch fails on fresh install 1.6

    Running the blast:launch command doesn't produce the expected result which would be to access either localhost:6006 or freshl9.test/storybook_preview and see StoryBook.

    Blast: 1.6 Laravel: 9.9.0 PHP: 8.1.4 Node: 17.8.0

    Also to node, the process keeps running until I ^C which you can notice in the log below.

    Here's the console output.

    [0] info @storybook/server v6.4.9
    [0] info 
    [0] (node:63163) DeprecationWarning: --static-dir CLI flag is deprecated, see:
    [0] 
    [0] https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated---static-dir-cli-flag
    [0] (Use `node --trace-deprecation ...` to show where the warning was created)
    [0] info => Loading presets
    [0] info => Serving static files from /freshl9/public at /
    [0] info => Loading custom manager config
    [0] info => Using PostCSS preset with [email protected]
    [0] info => Using default Webpack5 setup
    [0] info => Loading custom manager config
    [0] <i> [webpack-dev-middleware] wait until bundle finished
    [0] <i> [webpack-dev-middleware] wait until bundle finished
    [0] node:internal/crypto/hash:67
    [0]   this[kHandle] = new _Hash(algorithm, xofLen);
    [0]                   ^
    [0] 
    [0] Error: error:0308010C:digital envelope routines::unsupported
    [0]     at new Hash (node:internal/crypto/hash:67:19)
    [0]     at Object.createHash (node:crypto:135:10)
    [0]     at BulkUpdateDecorator.hashFactory (/freshl9/vendor/area17/blast/node_modules/webpack/lib/util/createHash.js:145:18)
    [0]     at BulkUpdateDecorator.update (/freshl9/vendor/area17/blast/node_modules/webpack/lib/util/createHash.js:46:50)
    [0]     at OriginalSource.updateHash (/freshl9/vendor/area17/blast/node_modules/webpack/node_modules/webpack-sources/lib/OriginalSource.js:131:8)
    [0]     at NormalModule._initBuildHash (/freshl9/vendor/area17/blast/node_modules/webpack/lib/NormalModule.js:888:17)
    [0]     at handleParseResult (/freshl9/vendor/area17/blast/node_modules/webpack/lib/NormalModule.js:954:10)
    [0]     at /freshl9/vendor/area17/blast/node_modules/webpack/lib/NormalModule.js:1048:4
    [0]     at processResult (/freshl9/vendor/area17/blast/node_modules/webpack/lib/NormalModule.js:763:11)
    [0]     at /freshl9/vendor/area17/blast/node_modules/webpack/lib/NormalModule.js:827:5
    [0]     at /freshl9/vendor/area17/blast/node_modules/loader-runner/lib/LoaderRunner.js:406:3
    [0]     at iterateNormalLoaders (/freshl9/vendor/area17/blast/node_modules/loader-runner/lib/LoaderRunner.js:232:10)
    [0]     at /freshl9/vendor/area17/blast/node_modules/loader-runner/lib/LoaderRunner.js:223:4
    [0]     at processTicksAndRejections (node:internal/process/task_queues:83:21) {
    [0]   opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
    [0]   library: 'digital envelope routines',
    [0]   reason: 'unsupported',
    [0]   code: 'ERR_OSSL_EVP_UNSUPPORTED'
    [0] }
    [0] 
    [0] Node.js v17.8.0
    [0] start-storybook --quiet -s /freshl9/public -p 6006 exited with code 1
    ^C
    [2] npm run watch-data exited with code SIGINT                                                                                                                                                                                                                          
    [1] npm run watch-components exited with code SIGINT
    

    Although accessing localhost:6006 has no response, accessing freshl9.test/storybook_preview throws a an exception.

    Too few arguments to function A17\Blast\Controllers\StoryController::__invoke(), 1 passed in /Users/rui.sardinha/dev/sites/freshl9/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php on line 48 and exactly 2 expected
    

    Let me know if I can provide more context.

    opened by csrui 2
Releases(1.7)
  • 1.7(Nov 15, 2022)

    Added

    • Auto import assets built using Vite. Blast automatically looks for your manifest file and loads the assets.

    Updated

    • Make storybook directive parsing more consistent with regular blade statements by @koenvu in https://github.com/area17/blast/pull/63
    • Fix deprecation notice in PHP 8.1 by @RVxLab in https://github.com/area17/blast/pull/54
    • Update Storybook to latest (6.5.13)
    • Update dependencies by @mrtimbrook in https://github.com/area17/blast/pull/56

    New Contributors

    • @RVxLab made their first contribution in https://github.com/area17/blast/pull/54
    • @koenvu made their first contribution in https://github.com/area17/blast/pull/63
    Source code(tar.gz)
    Source code(zip)
  • 1.6(Apr 6, 2022)

  • 1.5(Jan 5, 2022)

    Added

    • Auto-documentation for your Tailwind config. php artisan blast:generate-docs generates stories from your Tailwind config and publishes them to your app

    Updated

    • Storybook and addons to 6.4.9
    • DocsPage component now always has a white background
    Source code(tar.gz)
    Source code(zip)
  • 1.4.1(Dec 13, 2021)

  • 1.4.0(Nov 30, 2021)

    Added

    • Stories now display source code in a tab in the panel on the story view, and in the 'Docs' tab.
    • Expanded docs. You can now add more detail to your args which display in the 'Docs' tab - #26
    • Feature/add support for action event handlers - #29
    • Added support for 'asset groups' to allow different css and js files to be used on different components - #17

    Updated

    • Theming got a makeover - #26

    Removed

    • Blast asset publishing task during launch. Blast css now loads from preview.js within Storybook
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Nov 9, 2021)

    Added

    • Added checksum so that Storybook reloads the story if something outside the @storybook block has been changed - #15
    • Adds storybook global types in config - #16
    • Added the ability to set custom ordering on the story level or globally via the Blast config - #18

    Fixed

    • Center .blast-container
    • CORS headers are now set as part of the blast:launch task - #21

    Changed

    • Run GenerateStories as part of the Publish task
    • docs-page component updates:
      • Parse $description as markdown
      • Use wysiwyg styles for $description
      • Remove blast-wysiwyg class from slot wrapper to allow other components to be used within it
    Source code(tar.gz)
    Source code(zip)
  • 1.2.1(Oct 20, 2021)

  • 1.2.0(Oct 18, 2021)

    Added

    • Testbench setup with feature tests for the blast:demo and blast:generate-stories commands - #7
    • presetArgs support to @storybook directive - #10
    • Autoload CSS and JS assets from mix-manifest.json - #11

    Updated

    • Swap --noInstall option with --install in blast:launch task - #9
    • blast:publish now runs the same install check and method as blast:launch so you can publish a static storybook app without needing to run blast:launch first - #12
    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Sep 23, 2021)

  • 1.1.0(Sep 22, 2021)

    Added

    • blast:publish task to generate static Storybook app and publish to public folder

    Fixed

    • Issue preventing presetting non-array data
    • php 7.3 support
    Source code(tar.gz)
    Source code(zip)
Owner
AREA 17
AREA 17
Blade Snip allows you to use parts of a blade template multiple times. Basically partials, but inline.

Blade Snip Blade Snip allows you to use parts of a blade template multiple times. Basically partials, but inline: <div class="products"> @snip('pr

Jack Sleight 18 Dec 4, 2022
A package that uses blade templates to control how markdown is converted to HTML inside Laravel, as well as providing support for markdown files to Laravel views.

Install Install via composer. $ composer require olliecodes/laravel-etched-blade Once installed you'll want to publish the config. $ php artisan vendo

Ollie Codes 19 Jul 5, 2021
Use Laravel's Blade templating engine outside of Laravel.

Use Laravel's Blade templating engine outside of Laravel. This package provides a standalone version of Laravel's Blade templating engine for use outs

Ryan Chandler 22 Jan 2, 2023
A package to easily make use of Iconic icons in your Laravel Blade views.

Blade Iconic A package to easily make use of Iconic icons in your Laravel Blade views. For a full list of available icons see the SVG directory. Iconi

Malik Alleyne-Jones 17 Aug 25, 2022
A package to easily make use of Simple Icons in your Laravel Blade views.

Blade Simple Icons A package to easily make use of Simple Icons in your Laravel Blade views. For a full list of available icons see the SVG directory.

UB Labs 12 Jan 17, 2022
Laravel blade directives and php helpers for serverside rendered content, based on browser window size WITHOUT css

Laravel Window Size and Breakpoints Laravel blade directives and php helpers for server side rendered content, based on browser window size WITHOUT cs

Tina Hammar 7 Nov 23, 2022
Cagilo - a set of simple components for use in your views Laravel Blade.

Cagilo - a set of simple components for use in your views Laravel Blade. Official Documentation Documentation for Cagilo can be found on its we

Cagilo 151 Dec 6, 2022
Useful blade components and functionality for most Laravel projects.

laravel-base Note: Package is still in early stages of development, so functionality is subject to change. LaravelBase is a package I've created to pr

Randall Wilk 3 Jan 16, 2022
Create Laravel views (blade template) using 'php artisan' command-line interface

About LaraBit Have you ever wonder to create Laravel views (Blade Templates) using the same type of artisan commands that you usually use to create ne

Ragib MRB 5 Oct 15, 2021
An opinionated blade template formatter for Laravel that respects readability

blade-formatter An opinionated blade template formatter for Laravel that respects readability Online Demo Features Automatically Indents markup inside

Shuhei Hayashibara 277 Dec 26, 2022
Laravel Livewire (TALL-stack) form generator with realtime validation, file uploads, array fields, blade form input components and more.

TALL-stack form generator Laravel Livewire, Tailwind forms with auto-generated views. Support Contributions Features This is not an admin panel genera

TinaH 622 Jan 2, 2023
A Laravel Code Generator based on your Models using Blade Template Engine

Laravel Code Generator is a PHP Laravel Package that uses Blade template engine to generate code for you. The difference between other code generators

Victor Yoalli 59 Dec 5, 2022
Laravel 4 Blade on Steroids

Steroids v0.7 Laravel 4 Blade on Steroids This package provides some aditional features to Laravel Blade: Automatic command generation Create a file n

Antonio Carlos Ribeiro 97 Nov 29, 2022
Use Blade templates without the full Laravel framework

blade Use Laravel Blade templates as a standalone component without the full Laravel framework Full documentation is available at http://duncan3dc.git

Craig Duncan 138 Dec 7, 2022
Laravel blade directives and php helpers for serverside rendered content, based on browser window size WITHOUT css. Requires Livewire and AlpineJS.

Laravel Livewire Window Size and Breakpoints Laravel blade directives and php helpers for server side rendered content, based on browser window size W

Tina Hammar 15 Oct 6, 2022
A package to easily make use of SVG icons in your Laravel Blade views.

Blade Icons A package to easily make use of SVG icons in your Laravel Blade views. Originally "Blade SVG" by Adam Wathan. Turn... <!-- camera.svg -->

Blade UI Kit 1.7k Jan 2, 2023
Active State Helper for Laravel Blade

laravel-activehelper Active State Helper for Laravel Blade Lightweight and simple Introduction Basically we do like this. <li class="sidebar {{ Reques

Ahmad Irsyadul Ibad 4 Sep 25, 2022
API Blueprint Renderer for Laravel, customizable via Blade templates

API Blueprint Renderer for Laravel This Laravel package Blueprint Docs renders your API Blueprint. It comes with a standard theme that you can customi

Michael Schmidt-Voigt 225 Sep 16, 2022
This package adds syntax definitions for the Laravel Blade engine.

Laravel Blade Highlighter This package adds syntax definitions for the Laravel Blade engine. Works with various Sublime Text version, for older/specif

Eric Percifield 393 Dec 24, 2022