Conditional rendering of live components not working as expected in Phoenix Liveview

98 Views Asked by At

I am trying to display different live components depending on the device kind, so I have this in my template

<div phx-hook="SpecialScreenSize" id="screen-size"></div>

<div>
  <%= @device_kind %>  
  <%= if @device_kind == :mobile do %>
    <.live_component
      module={NextlairWeb.ListingLive.ShowComponents.ShowMobile}
      id="listing-mobile"
      current_user={@current_user}
      page_title={@page_title}
    />
  <% else %>
    <.live_component
    module={NextlairWeb.ListingLive.ShowComponents.ShowDesktop}
    id="listing-mobile"
    current_user={@current_user}
    page_title={@page_title}
   />
 <% end %> 
</div>

Unfortunately, the show_desktop live component is the one that's shown regardless of the device kind. I noticed when I remove the markup to display the live components and conditionally show the device kind, it works as expected. What could I be doing wrong?

1

There are 1 best solutions below

0
Danstan On

You are likely running a hook SpecialScreenSize to decide whether the screen size is mobile or desktop. The hook is executed later and you have to trigger a rerender from phoenix to update

This is better done with CSS. The screen size is a client parameter and CSS will help you do that.

My suggestion is to apply a hide CSS to the mobile component using a CSS @media selector. The CSS can be

.mobile, .desktop {
    display: none;
}

/* Media query for mobile screens */
@media only screen and (max-width: 767px) {
    .mobile {
        display: block; /* Show mobile on mobile screens */
        /* Add any other styles for mobile on mobile screens */
    }
}

/* Media query for larger screens (tablets and above) */
@media only screen and (min-width: 768px) {
    .desktop {
        display: block; /* Show desktop on larger screens */
        /* Add any other styles for desktop on larger screens */
    }
}

Now the components

<div class="mobile">
  <.live_component
      module={NextlairWeb.ListingLive.ShowComponents.ShowMobile}
      id="listing-mobile"
      current_user={@current_user}
      page_title={@page_title}
  />
</div>

<div class="desktop">
  <.live_component
    module={NextlairWeb.ListingLive.ShowComponents.ShowDesktop}
    id="listing-mobile"
    current_user={@current_user}
    page_title={@page_title}
   />
</div>

If you are using tailwind css

<div class="block md:hidden">
    Mobile component
</div>

<div class="hidden md:block">
    Desktop Component
</div>