kevinpapst / TablerBundle

Tabler.io bundle for Symfony 6 - admin theme for easy integration, coming with Bootstrap 5.3, Webpack-Encore integration and many more features...
MIT License
96 stars 19 forks source link

support ux components #173

Open tacman opened 1 year ago

tacman commented 1 year ago

I'm a huge fan of Symfony UX Components, and greatly prefer them to macros. I think it's worth considering supporting them in this bundle as well.

In addition to not needing the import, I find the syntax cleaner, and of course the big benefit is that you can inject services, like security. Plus, setting defaults and handling logic is easier in PHP than in Twig.

// using macros
{% from '@Tabler/components/alert.html.twig' import alert %}
{{ alert({title : 'Title V2', description: 'Description V2', icon : 'warning', dismissible : true}) }}

// using a component
<twig:alert title="Title V2" description="Description" icon='warning' dismissable="true" />

{# Since often the data passed to the component is dynamic, it's even shorter, from a different theme bundle  #}

                    {% for bsClass in bootstrap_theme_colors() %}
                        {% set message ="Look, a %s alert — check it out!"|format(bsClass)   %}
                        <twig:alert :message="message" :type="bsClass" />
                    {% endfor %}

There's a lot of power in the UX components, I have a whole set of them that I wrote for the sneat theme that would likely port pretty easily.

kevinpapst commented 1 year ago

I didn't use them by now, as I had no real interest in the entire JS stack around it. But the components looked good to me as well. Do you want to make an proposal PR? I am happy to look into and probably integrate it, as long as I do not have to use the Stimulus stuff then.

tacman commented 1 year ago

You don't HAVE to use stimulus, but you get to! I love Stimulus. But no, twig components don't require it.

Before integrating components into the bundle, I added one into the demo app, since it's easier to work with during the brainstorming/prototyping stage.

While it might look like simply a syntax change, I find components much easier to develop. For example, see the Alert.php code here, I put setting the defaults in Twig in a comment, I find setting PHP defaults easier.

https://github.com/tacman/TablerBundle-Demo/commit/6a976d5e225e4f45cd7d5ab33ed989a5495e65a8

Then we can drop the {% if variable is not empty %}, since we are setting all the variables in php and passing them.

A question for discussion: namespaces. That is, if it were integrated into the tabler bundle, how should alert be called? Options:

* <twig:Alert>
* <twig:alert>
* <twig:tabler:alert>

I'm slightly leaning toward prefixing it with tabler, in part because my Bootstrap bundle currently uses another theme (sneat), and at one point had supported adminkit. Hmm, I wonder if it's possible to be a bundle setting?

Anyway, continuing the brainstorming, macros could then be a simple wrapper around the ux components, so avoid code duplication. I was brainstorming on the Symfony Discussions board about this issue here:

https://github.com/symfony/symfony/discussions/51755

Here's the demo page now. Because of the way twig interprets strings, I had a hard time putting the actual twig code insides the codeTemplates for debugging, because it kept getting parsed.

image

cavasinf commented 1 year ago

Hey @tacman, we already talked about this part of Symfony UX in this discussion 😄

Are you using it in your projects? We have not yet taken that step on our side. You may have an answer to my current problem with the state of the macro/component here.

Are you able to use StimulusBundle function inside component params?

With the current state, if we want to use stimulus actions/params, we have to write all attrs for stimulus explicitly:

{% from '@Tabler/components/button.html.twig' import button %}

{{ button('calendar', {
    title: 'label.date.notification'|trans,
    combined: false,
    attr: { 
         'data-modal-form-target': 'submitButton',
         'data-action' : 'modal-form#submitForm',
         'data-modal-form-refresh-on-success-param': false,
    },
}, 'primary') }}

At the end, when using stimulus complex logic, we do not use Tabler macros anymore, but straight HTML with the Symfony StimulusBundle.

<a
      class="btn btn-primary" href="#"
      data-bs-toggle="tooltip" data-bs-placement="top"
      title="{{ 'label.date.notification'|trans }}"
      {{ stimulus_target('modal-form', 'submitButton') }}
      {{ stimulus_action('modal-form', 'submitForm', null, {
          refreshOnSuccess: false,
      }) }}
>{{ tabler_icon('calendar') }}</a>

The downside of this is that we lose CamelCase param naming for dash-case. When searching for param/action usage, there's no hint to find where it's used or configured.

thePanz commented 12 months ago

I really like the approach from @tacman where twig-components can be used instead of macros.

Watching Ryan Weaver implementing that, he had an idea about having tabler icons being twig components too. How to use them? Simply like: <twig:tabler-icon("plus") /> (this is a simplified example, tho

Would it be possible to start or continue the work from @tacman and migrate to TwigComponents? WDYT?

tacman commented 12 months ago

Here's a site that uses some of my bundles to create grids (aka datatables) without a build step. That is, no npm or yarn or webpack. It does use Stimulus, but fundamentally simulus isn't required. Well, required for my datatables bundles, but not for things like the card component.

https://dt3-demo.survos.com/

BUT relevant to this conversation, it also uses the card component, from my bootstrap bundle.

                    {% component card with {} %}
                        {% block title 'Simple Datatables' %}
                        {% block text %}
                            <p>
                                A wrapper around simple datatables.
                                Pros: no dependencies, just one js file and one css file.
                                Simple.
                            </p>
                            <p>
                                For example, the credits links use simple-datatables
                            </p>
                        {% endblock %}
                        {% block links %}
                            <div class="demo-inline-spacing">
                                <a href="https://github.com/fiduswriter/simple-datatables/" target="_blank"
                                   class="btn btn-outline-primary">Simple Datatables Library</a>
                                <a href="https://github.com/survos/SurvosSimpleDatatablesBundle" target="_blank"
                                   class="btn btn-outline-success">Simple Datatables Bundle</a>
                            </div>
                        {% endblock %}
                    {% endcomponent %}

I'll be moving the links and buttons to the components shortly, but wanted to show you what I've done. It's soooo much easier than using macros.

I have a few Bootstrap components converted to twig components: https://github.com/survos/BootstrapBundle/tree/master/src/Components

And not surprisingly they work as expected when switching out bootstrap themes like bootswatch. The tabler css will also work for the basic bootstrap 5 components.

I'll continue to work on these and will post an example with the tabler css. Happy to share what I've learned during this process.

tacman commented 12 months ago

Actually, here's a better example, as all of the pages are focused on the components (and there's no stimulus!)

https://bootstrap-demo.survos.com/

The repo is at https://github.com/tacman/bootstrap-demo

Install and run it locally in less than a minute:

git clone git@github.com:tacman/bootstrap-demo.git && cd bootstrap-demo 
composer install 
bin/console importmap:install
symfony server:start -d 
symfony open:local

There's no custom javascript beyond loading the libraries and css, the only javascript that's loaded is the core bootstrap library (and popper). The debug toolbar shows all the component information as well now.