area17 / blast

Storybook for Laravel Blade 🚀
https://dev.to/area17/getting-started-with-blast-storybook-for-laravel-blade-c5c
Apache License 2.0
270 stars 39 forks source link

How to implement component slots and named slots? #75

Open mikebronner opened 1 year ago

mikebronner commented 1 year ago

Let's say we have a component that uses slots, how should that be defined in the storybook args?

For example, a more complex component that uses slots and sub-components:

<x-ui.buttons.general
    class="flex items-center gap-2 px-4 py-1 text-gray-600 border border-gray-500 rounded-md hover:bg-gray-500 hover:text-gray-100"
>
    <x-slot
        name="loadingIcon"
    >
        <x-icons.solid.cog
            class="w-4 h-4 shrink-0"
        />
    </x-slot>
    <x-slot
        name="icon"
    >
        <x-icons.light.csv
            class="w-4 h-4 shrink-0"
        />
    </x-slot>
    <span>
        Export To CSV
    </span>
</x-ui.buttons.general>
mrtimbrook commented 1 year ago

Hi! Are you wanting to define the icon component in the args? Storybook limits us to using only simple data so you could create a dropdown (using args and argTypes) with the names of the things you want to pass to the slot and handle the logic in your story blade view.

If you just want to change the names of the icons in the slots you could do something like in your story file:

@storybook([
    'args' => [
        'icon' => 'icons.light.csv',
        'loadingIcon' => 'icons.solid.cog',
        'label' => 'Export to CSV'
    ]
])

<x-ui.buttons.general
    class="flex items-center gap-2 px-4 py-1 text-gray-600 border border-gray-500 rounded-md hover:bg-gray-500 hover:text-gray-100"
>
    <x-slot
        name="loadingIcon"
    >
        <x-dynamic-component
            :component="$loadingIcon"
            class="w-4 h-4 shrink-0"
        />
    </x-slot>
    <x-slot
        name="icon"
    >
        <x-dynamic-component
            :component="$icon"
            class="w-4 h-4 shrink-0"
        />
    </x-slot>
    <span>
        {{ $label }}
    </span>
</x-ui.buttons.general>
mikebronner commented 1 year ago

@mrtimbrook thanks for following up and explaining how Storybook uses data. In Laravel, as you know, components can have complex data types passed, which is a challenged, as well as nested components (like slots and components inside components), so rendering the outside component is exponentially difficult the more nesting you have.

Since you can pass any blade content (PHP, HTML, etc.) in slots, I was wondering how those are usually handled in Storybook, i.e. by having a textarea field where the user can specify html content, pre-populated with default values?

ifox commented 1 year ago

The goal of Storybook is to render "stories" of your components. A story is meant to demonstrate usage of a component. A component having a slot, or multiple slots, is best demonstrated with these slots having content in them. But the slots are not what you are demonstrating. What you put inside slots is something you would most likely demonstrate in separate stories.

Now, you can still make the slot entirely dynamic by using an arg that receives html from a textarea control, but that's kind of against the nature of the tool. Instead, you could use a control to let your storybook users select from different options of what the content of the slot could be, like different icons, and let them change the text of your dummy slot content. That's what @mrtimbrook was suggesting.

mikebronner commented 1 year ago

@ifox Thanks for the added context. Yea, I get that. :) Too bad that Storybook doesn't accommodate rendering defined components within a component. :) I was hoping there was some magic I could implement.