larowlan / vite-plugin-twig-drupal

Provides a vite plugin for rendering Drupal flavoured twig files with Storybook
MIT License
16 stars 6 forks source link

Difficulty Rendering Single Directory Component with Subcomponent in Storybook #29

Closed kalevitan closed 5 hours ago

kalevitan commented 1 day ago

I’m relatively new to Storybook, and I’m not entirely sure if this is an expected use case, but I’ve encountered a challenge while exploring the framework and tooling.

I am trying to render a Single Directory Component (SDC) that includes a subcomponent, specifically a card that utilizes a button component. Here’s a snippet of the problematic logic from my card.twig:

./components/card/card.twig

<div class="card">
  <div class="card__image">...</div>
  <div class="card__title">...</div>
  <div class="card__button>
    {% include 'my_theme:button' with {
      'link_url': link_url,
      'link_title': link_title,
    } only %}
  </div>
</div>

When attempting to include the button component, I receive the following error thrown from the button template:

[plugin:vite:import-analysis] Failed to resolve import "/Users/*****/Projects/storybook/components/button/button" from "components/card/card.twig". Does the file exist?
/Users/****/Projects/storybook/vitejs/components/card/card.twig:7:17
5  |          
6  |  
7  |          import '/Users/*****/Projects/storybook/components/button/button';

The card component doesn't render either:

Failed to fetch dynamically imported module: http://localhost:6006/components/card/card.stories.js

I've dumbed-down my button component to something basic, like <button>test</button>

Here’s a snippet of my Vite configuration:

export default defineConfig({
  plugins: [
    twig({
      namespaces: {
        components: join(__dirname, "../components"),
        my_theme: join(__dirname, "../components"),
      },
    }),
  ],
});

Currently, I am not running this in a Drupal theme; it’s more of a proof of concept. Any insights or suggestions on how to resolve this issue would be greatly appreciated!

larowlan commented 1 day ago

What if you use my_theme:button.twig ? We could auto-add support for that if that works

larowlan commented 1 day ago

According to our tests, shouldn't need that - https://github.com/larowlan/vite-plugin-twig-drupal/blob/main/tests/fixtures/mockup.twig#L18 but maybe we do with two layers of nesting

kalevitan commented 7 hours ago

Thanks for the quick response. I tried that as well with my prototype, but that's not compatible with Drupal. I also tried embed instead of include, as well as an attempt to modify the Twig.logic.type.include. Neither effort could render the nested component.

larowlan commented 7 hours ago

Let me knock up a quick test of embedding

larowlan commented 6 hours ago

https://github.com/larowlan/vite-plugin-twig-drupal/pull/30 seems to pass so nested embeds look to work

kalevitan commented 5 hours ago

@larowlan, thanks for your help! It turns out the issue was related to my twig namespaces. While my original paths were working for standalone components, I should have noticed that the path in the error was looking one directory up than it should. Once I update the paths to point to the project root, subcomponents worked as expected:

plugins: [
    twig({
      namespaces: {
        components: join(__dirname, "/components"),
        my_theme: join(__dirname, "/components"),
      },
    }),
  ],

However, I now see new issue with subcomponents now that they are rendering. When using includes or embeds, the attributes.addClass(classes) in the subcomponent does not seem to parse properly:

Parent component render:

...
<button button,button--primary,button--medium,inline-block="" href="https://www.drupal.org">
      Drupal Card
  </button>

If I view the component on it's own, the classes are properly parsed using the class attribute:

<button class="button button--primary button--medium inline-block" href="https://www.drupal.org">
      Drupal
  </button>

Could you try including that in your test? Thanks again

larowlan commented 5 hours ago

can you share the twig of the components (parent and child)? I can use them in the test

kalevitan commented 5 hours ago

card.twig

{% set classes = [
  'border',
  'border-2',
  'border-baseOne',
  'card',
  'content-grid--item',
  'grid',
  'rounded',
  'p-5',
  ]
%}

<div{{ attributes.addClass(classes) }}>

  {% block card_media %}
    {% if image %}
      <div class="card__image pb-2">
        {{ image }}
      </div>
    {% endif %}
  {% endblock card_media %}

  {% block card_body %}
    {% if headline %}
    <header class="card__headline">
      <h3 class="h2 font-bold mb-2">{{ headline }}</h3>
    </header>
    {% endif %}

    {% set description = description|render %}
    {% if description %}
      <div class="card__description">
        {{ description }}
      </div>
    {% endif %}

    {% if link_url %}
      <div class="card__link pt-4">

      {% include 'urbi:button' with {
        elm: 'button',
        link_url: link_url,
        link_title: link_title,
      } only %}

      {# {% embed "urbi:button" with {
        elm: 'button',
        style: 'secondary',
        size: 'small',
      } only %}
        {% block content %}
          <i class="fa fa-alert"></i>
          <span>This is a Button Override!</span>
        {% endblock %}
      {% endembed %} #}

      </div>
    {% endif %}
  {% endblock card_body %}
</div>

button.twig

{%
  set classes = [
    'button',
    'button--' ~ style|default('primary'),
    'button--' ~ size|default('medium'),
    'inline-block',
  ]
%}

{{ attributes.addClass(classes) }}

<{{ elm|default('a') }}
  {{ attributes.addClass(classes) }}
  {{ link_url ? 'href=' ~ link_url : '' }}
  {{ onclick ? 'onclick=' ~ onclick : '' }}
  >
  {% block content %}
    {{ link_title|default('Submit'|t) }}
  {% endblock %}
</{{ elm|default('a') }}>
larowlan commented 5 hours ago

try changing it to this

 {# {% embed "urbi:button" with {
        elm: 'button',
        style: 'secondary',
        size: 'small',
       attributes: create_attribute()
      } only %}
kalevitan commented 5 hours ago

That worked! Thanks again for your help and this plugin.

larowlan commented 5 hours ago

:dancers: