defmodule FloUI.Tabs do alias Scenic.Graph alias Scenic.Primitive @moduledoc ~S""" ## Usage in SnapFramework The following example uses FloUI.Tabs and Grid to lay the tabs out. Iterates over the @tabs assign to render each tab. @module.get_tab_width runs FontMetrics on the label to get the width. ``` elixir <%= graph font_size: 20 %> <%= component FloUI.Tabs, {@active_tab, @tabs}, id: :tabs do %> <%= component FloUI.Grid, %{ start_xy: {0, 0}, max_xy: {@module.get_tabs_width(@tabs), 40} } do %> <%= for {{label, cmp}, i} <- Enum.with_index(@tabs) do %> <%= component FloUI.Tab, {label, cmp}, selected?: if(i == 0, do: true, else: false), id: :"#{label}", width: @module.get_tab_width(label), height: 40 %> <% end %> <% end %> <% end %> ``` """ use SnapFramework.Component, name: :tabs, template: "lib/tabs/tabs.eex", controller: FloUI.TabsController, assigns: [ active_tab: nil, active_pid: nil, tabs: nil ], opts: [] defcomponent :tabs, :any use_effect [assigns: [active_tab: :any]], [ run: [:on_tab_change] ] def setup(%{assigns: %{data: {active_tab, tabs}}} = scene) do scene |> assign(active_tab: active_tab, tabs: tabs) end def process_info({:tab_pid, pid}, scene) do {:noreply, assign(scene, active_pid: pid)} end def process_event( {:select_tab, cmp}, pid, %{assigns: %{active_tab: active_tab, active_pid: active_pid}} = scene ) when cmp != active_tab do GenServer.call(active_pid, {:put, false}) scene = scene |> assign(active_tab: cmp, active_pid: pid) {:cont, {:select_tab, cmp}, scene} end def process_event({:select_tab, _cmp}, _pid, scene) do {:noreply, scene} end def process_event(event, _, scene) do {:cont, event, scene} end end