defmodule Moon.Design.BottomSheet do @moduledoc false use Moon.StatefulComponent @doc "Whether the BottomSheet is open or not" prop(is_open, :boolean, default: false) @doc "Called when the BottomSheet is dismissed" prop(on_close, :event) @doc """ Deprecated: Whether the BottomSheet has a shadow or not """ prop(has_shadow, :boolean, default: false) @doc """ Deprecated: The size of the BottomSheet, sm, md, lg or custom pixel/percentage/rem value """ prop(size, :string, values!: [ "sm", "md", "lg" ], default: "sm" ) @doc "Tailwind classes for customization" prop(class, :css_class) @doc "Data-testid attribute for DOM element" prop(testid, :string) @doc """ Experimental: makes BottomSheet behave as Modal on some screen widths, please reffer to https://tailwindcss.com/docs/screens """ prop(as_modal_on, :string, values: ~w(sm md lg xl 2xl)) @doc "Panel of BottomSheet, see BottomSheet.Panel" slot(panel, required: true) @doc "Backdrop of BottomSheet, see BottomSheet.Backdrop" slot(backdrop) # internal API @doc "Internal API, used for transition of the element" data(is_closing, :boolean, default: false) def render(assigns) do ~F"""
" flex"} data-testid={@testid} > <#slot {@backdrop} /> <#slot {@panel} context_put={ on_close: @on_close || %{name: "start_closing_bottom_sheet", target: @myself}, has_shadow: @has_shadow, as_modal_on: @as_modal_on, size: @size } />
""" end def open(bottom_sheet_id) do send_update(__MODULE__, id: bottom_sheet_id, is_open: true) end def close(bottom_sheet_id) do send_update(__MODULE__, id: bottom_sheet_id, is_closing: true) end def handle_event("set_open", _, socket) do {:noreply, assign(socket, is_open: true)} end def handle_event("start_closing_bottom_sheet", _, socket) do {:noreply, assign(socket, is_closing: true)} end def handle_event("stop_closing", _, socket) do {:noreply, assign(socket, is_closing: false)} end def handle_event("set_close", _, socket) do {:noreply, assign(socket, is_open: false, is_closing: false)} end defp modal_classes(nil), do: [] defp modal_classes(size) do ~w(hidden items-center justify-center) |> Enum.map(&"#{size}:#{&1}") end end