Petal and Surface LiveView

Is it possible to use Petal styled components with the Surface LiveView or the two libraries are incompatible?
Are there any examples that use both?

Not sure what you exactly mean by “petal styled component” but a quick search for “how to use petal stack” and you’ll find heaps of information on using Phoenix Elixir Tailwind Alpine Liveview and then you can throw Surface to get nice PETALS power.

And just to be clear, yes, you can pair those together.

What seems confusing is that Petal components are defined with function handling tags, e.g. <.button>...</.button>, whereas a surface has a different syntax for the same components, e.g. <Button>...</Button>. So, if using both libraries, how do you define a button, so that it’s parsed by the Surface’s compiler, and followed by invocation of Petal’s tag handling functions? If you could provide a small example that would be very helpful.

You can use Phoenix components in Surface.

defmodule RemixIcon do
  @moduledoc "Function components for Remix Icon SVGs"
  use Phoenix.Component

  @doc "Business/bar-chart-box-line.svg"
  def ri_bar_chart_box_line(assigns) do
    assigns = assign_new(assigns, :class, fn -> "w-6 h-6" end)

    ~H"""
    <svg class={@class} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
      <path fill="currentColor" d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm1 2v14h16V5H4zm3 8h2v4H7v-4zm4-6h2v10h-2V7zm4 3h2v7h-2v-7z"/>
    </svg>
    """
  end
end
defmodule SomeWeb.SomeLive do
  use Surface.LiveView
  
  def render(assigns) do
    ~F"""
    <RemixIcon.ri_add_line class="h-5 w-5" />
    """
  end
end

Yes, your example is clear. What about the case when both libraries have a custom definition of alike components, such as a form or a form field, and you’d like to use Surface template syntax, but apply Petal’s component styling customization, e.g.:

# Surface:

<Form for={:user}>
  <Field name={:email}>
    <Label>E-mail</Label>
    <TextInput value={@user["email"]}/>
  </Field>
</Form>

# Petal:

<.form let={f} for={:user}>
  <.form_label form={f} field={:email}/>
  <.text_input form={f} field={:email}/>
  <.form_field_error form={f} field={:email}/>
</.form>

Since they seem to be redundant, does this mean that if you want to use Petal’s <.form ...> you can’t use Surface’s <Form ...> or there’s a way to make them co-exist?

Well you can’t use both <.form ...> and Form at the same time so you need to pick one. Surface uses <.form...> inside Form but there is all the Context stuff still there until the next version. If you want Surface syntax but want it to look like their components, you could steal the CSS/JS from Petal and make your own components, or you can wrap them (like Form wraps form) if you really want those sweet, sweet capital letters.