<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="168166" data-post-id="168166">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="elcritch" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/elcritch/120/15758_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  elcritch
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="Menkir" data-post="11" data-topic="29988" data-full="true">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/menkir/48/15343_2.png" class="avatar"> Menkir:</div>
<blockquote>
<p>Cool project. I am currently working with LiveComponents and Bulma myself. I wrote generic Bulma widgets to reuse them. Are you also planning to integrate the additional Bulma extensions on wikiki?</p>
</blockquote>
</aside>
<p>I find making a library out of my internal widgets helps keep me a bit more disciplined in documenting them. Plus maybe others find them useful. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"> Not currently planning on adding Bulma extensions as I don’t use them currently, but I’d be willing to accept PR’s.</p>
<aside class="quote no-group" data-username="ondrej-tucek" data-post="12" data-topic="29988">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ondrej-tucek/48/11566_2.png" class="avatar"> ondrej-tucek:</div>
<blockquote>
<p>Don’t mind, it’s use to free. If I understand it correctly your Bulma Widgets behave as the source of truth, right? Maybe that’s the reason why is a composition of components so complicated. Just an idea, instead of using <code>update</code> function, define for each component a couple functions like <code>handle_event/handle_info/..</code> which would provide a communication between these components.</p>
</blockquote>
</aside>
<p>Great! I used yours to see how I could model something like a card component. I tried a few variations and ended up liking a pattern of using a case statement in a do block with the <code>LiveComponent</code>s as the Source-of-Truth. Though I also provide a “default” setup using proplist options for cases where you would want standard buttons, like this:</p>
<pre><code>    &lt;%= live_component @socket, CardComponent, 
                   id: :card1, 
                   footers: ["Save Item": "card-1-save"] do %&gt;
      &lt;%= case @item do %&gt;
        &lt;% :content_item -&gt; %&gt;
          Lorem ipsum dolor sit amet, consectetur adipiscing elit.
          Phasellus nec iaculis mauris. &lt;a&gt;@bulmaio&lt;/a&gt;.
          &lt;a href="#"&gt;#css&lt;/a&gt; &lt;a href="#"&gt;#responsive&lt;/a&gt;
          &lt;br&gt;
          &lt;time datetime="2016-1-1"&gt;11:09 PM - 1 Jan 2016&lt;/time&gt;
        &lt;% _other -&gt; %&gt;
      &lt;% end %&gt;
    &lt;% end %&gt;
</code></pre>
<p>It turns out that using the do-block actually makes composability pretty straightforward, even using the parent LiveView assigns (<code>@modal_va</code> is set in the parent <code>LiveView</code>) works! I’m pretty happy with the composability, even though you have to write a case statement. A macro would be nice to handle that but broke when I tried it.</p>
<p>You can also mix and match from default event handlers or custom ones like in this example. Note the <code>save-button</code> targets the parent LiveView while the <code>cancel-button</code> uses the default cancel handler:</p>
<pre><code>    &lt;%= live_component @socket, ModalComponent, id: :modal2 do %&gt;
      &lt;%= case @item do %&gt;
        &lt;% :header -&gt; %&gt;
          &lt;p class="modal-card-title"&gt;Second Modal&lt;/p&gt;
          &lt;button class="delete" phx-click="delete" phx-target="&lt;%= @target %&gt;" aria-label="close"&gt;
        &lt;% :footer -&gt; %&gt;
          &lt;button class="button is-success" phx-click="modal-2-save" &gt;
            Save changes
          &lt;/button&gt;
          &lt;button class="button" phx-click="cancel" phx-target="&lt;%= @target %&gt;"&gt;
            Cancel
          &lt;/button&gt;
        &lt;% _other -&gt; %&gt;
      &lt;% end %&gt;
    &lt;% end %&gt;
</code></pre>
<p>Originally I tried using the parent <code>LiveView</code> as the Source-of-Truth, but it seems you can’t define <code>handle_event</code>’s without providing an <code>id</code> and state in the <code>LiveComponent</code> (in LiveView v0.9.0). Between that and having two spots to define/configure the widgets felt confusing and a bit cumbersome. So having the widgets send events to the parent <code>LiveView</code> allows a pretty simple interaction between widgets that seems pretty simple and robust so far. Though documenting it well is the tricky part.</p>
<p>Also there are helper functions to do things like open/close/update a widget like:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def handle_event("modal-1-save", _params, socket) do
    {:noreply, socket |&gt; widget_close(:modal1)}
  end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="168166" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/bulma-widgets-livecomponent-wrappers-using-bulma/29988/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-168166" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="168166"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="336910" data-post-id="336910">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="elcritch" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/elcritch/120/15758_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  elcritch
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve been working on re-writing my previous bulma widgets library to modernize it. There’s basic components for most of the basic bulma elements. There are also a few initial stateful live components for dropdowns and menus.</p>
<p>The library also includes the necessary Bulma CSS files for easy setup.</p>
<p>A big part of the re-write focuses on changing how the state of widgets is handled. There’s an event system which provides out-of-the-box support for updating shared values from a parent liveview in child live components. There’s also support for cached values and broadcasting values. I’m still working on documenting the design, but the api’s in what I think is a useable state.</p>
<p>The goal is easy development for small scale app style UIs for Nerves devices.</p>
<p><a href="https://github.com/elcritch/bulma_widgets2/" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/elcritch/bulma_widgets2/</a></p>
<p>Here’s the examples I’ve been developing with:</p>
<p><a href="https://github.com/elcritch/bulma_widgets2/blob/main/lib/bulma_widgets_web/live/widget_examples_live.ex" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/elcritch/bulma_widgets2/blob/main/lib/bulma_widgets_web/live/widget_examples_live.ex</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="336910" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/bulma-widgets-livecomponent-wrappers-using-bulma/29988/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-336910" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="336910"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="337207" data-post-id="337207">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="elcritch" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/elcritch/120/15758_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  elcritch
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Got a bunch more changes done and added some tests to verify the data sharing system. The handling of slots and a few other of the bulma components and elements have been improved.</p>
<p>I also put up the widgets example page on my personal website. If you open the widgets examples on two different tabs or browsers and select options under the “Shared and Cached Dropdown” menu you’ll see how it syncs the selections between them!</p>
<p>You can check it out here:</p>
<p><a href="https://elcritch.net/widgets.html" class="onebox" target="_blank" rel="noopener nofollow ugc">https://elcritch.net/widgets.html</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337207" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/bulma-widgets-livecomponent-wrappers-using-bulma/29988/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-337207" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337207"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>