PhoenixKitProjects.Web.Components.SmartLink (PhoenixKitProjects v0.4.0)

Copy Markdown View Source

Embed-mode aware link.

In navigate mode renders a plain <.link navigate={...}> — the browser sees a real <a href>, right-click-open-new-tab works, screen readers see a link, prefetch works.

In emit mode renders a <button phx-click="open_embed"> that fires the shared open_embed event (intercepted by the hook attached via PhoenixKitProjects.Web.Helpers.attach_open_embed_hook/1 in each LV's mount/3). The hook validates the target LV against Helpers.embeddable_lvs/0 and broadcasts {:projects, :opened, %{lv, session, frame_ref}} on the host topic.

Use everywhere this module currently uses <.link navigate={...}> to another module LV.

Example

<.smart_link
  navigate={Paths.project(project.uuid)}
  emit={{PhoenixKitProjects.Web.ProjectShowLive, %{"id" => project.uuid}}}
  embed_mode={@embed_mode}
  class="link link-hover"
>
  {Project.localized_name(project, lang)}
</.smart_link>

Why both attrs are required

Even in emit mode, navigate is required as a fallback — if the whitelist rejects the target, the hook returns {:cont, socket} and the LV's own handler can fire, but most call sites simply have no handler, so the click is a no-op. A future tweak could make the hook fall back to push_navigate(navigate) in that case; for now, whitelist mismatches are surfaced via Logger.warning from the hook itself.

Summary

Functions

smart_link(assigns)

Attributes

  • navigate (:string) (required)
  • emit (:any) (required) - {TargetLV :: module(), session_overrides :: map()}.
  • embed_mode (:atom) - Socket's :embed_mode assign. Defaults to :navigate so LVs that haven't been converted yet (or that forget to pass it) get safe browser-navigation behaviour. Defaults to :navigate. Must be one of :navigate, or :emit.
  • class (:string) - Defaults to nil.
  • Global attributes are accepted. Supports all globals plus: ["title", "aria-label", "data-id"].

Slots

  • inner_block (required)