Packages
primer_live
0.11.0
An implementation of GitHub's Primer Design System for Phoenix LiveView.
Current section
Files
Jump to
Current section
Files
lib/helpers/prompt_declaration_helpers.ex
defmodule PrimerLive.Helpers.PromptDeclarationHelpers do
@moduledoc false
alias Phoenix.LiveView.JS
defmacro id(name_element_id, the_element, is_required) do
quote do
attr(:id, :string,
required: unquote(is_required),
doc:
if unquote(is_required) do
"""
{name_element_id}, used for opening and closing from the outside.
"""
|> String.replace("{name_element_id}", unquote(name_element_id))
else
"""
{name_element_id}. While passing the ID is optional, it is required:
- For referencing {the_element} from other functions or components, such as for opening and closing.
- For maintaining an open state after making selections.
- To get consistent IDs in tests.
If not set, an ID is derived from `form` and `field`, or otherwise generated randomly.
"""
|> String.replace("{name_element_id}", unquote(name_element_id))
|> String.replace("{the_element}", unquote(the_element))
end
)
end
end
defmacro is_dropdown_caret(default) do
quote do
attr :is_dropdown_caret, :boolean,
default: unquote(default),
doc: "Adds a dropdown caret icon to the toggle button."
end
end
defmacro is_backdrop do
quote do
attr :is_backdrop, :boolean,
default: false,
doc: """
Generates a backdrop background with a default strength and tint values.
Default backdrop strenght:
- dialog and drawer: `"medium"`
- menus: `"light"`
Default tint: "dark".
"""
end
end
defmacro backdrop_strength do
quote do
attr :backdrop_strength, :string,
values: ["medium", "strong", "light", nil],
default: nil,
doc: """
Backdrop strenght. Overrides the default value from `is_backdrop`.
"""
end
end
defmacro backdrop_tint do
quote do
attr :backdrop_tint, :string,
values: ["dark", "light", nil],
default: nil,
doc: """
Backdrop tint. Overrides the default value from `is_backdrop`.
"""
end
end
defmacro is_fast(default_value) do
quote do
attr :is_fast, :boolean,
default: unquote(default_value),
doc: """
Generates fast fade transitions for backdrop and content.
"""
end
end
defmacro toggle_slot(the_element) do
quote do
slot :toggle,
required: true,
doc:
"""
Generates a button to open {the_element}.
A `phx-click` attribute is added automatically if it is not passed in the slot attributes.
Any custom class will override the default class "btn".
"""
|> String.replace("{the_element}", unquote(the_element)) do
attr(:class, :any,
doc: """
Additional classname.
"""
)
attr(:style, :string,
doc: """
Additional CSS styles.
"""
)
attr(:"phx-click", :any,
doc: """
Phoenix click function. Overrides the default toggle function.
"""
)
attr(:"phx-target", :any)
attr(:"aria-label", :string)
attr(:rest, :any,
doc: """
Additional HTML attributes added to the item element.
"""
)
end
end
end
# Dialog, drawer and menu specific
defmacro is_show(the_element, component_tag) do
quote do
attr :is_show, :boolean,
default: false,
doc:
"""
Sets the display state of {the_element}. Control conditional display by using Phoenix's `:if` attribute.
Example:
```
<{component_tag} is_show :if={@live_action in [:new, :edit]}>
...
</{component_tag}>
```
"""
|> String.replace("{the_element}", unquote(the_element))
|> String.replace("{component_tag}", unquote(component_tag))
end
end
defmacro show_state(the_element) do
quote do
attr :show_state, :string,
values: ~w(default onset hold),
default: "default",
doc:
"""
Use when {the_element} is already displayed, and should be persisted when navigating to another LiveViews (for example to hide {the_element} with a transition after having navigated to a new route). This method does require that {the_element} is available on the other LiveView page, so it is best suited for "global" components such as navigation panels and app header menus.
Use together with `is_show`.
Values:
- "default": No change.
- "onset": Preparation for the "hold" state. Removes the "phx-remove" attribute so that navigating away doesn't cause a close transition.
- "hold": Removes the "phx-remove" attribute as well as opening transitions and first focus.
"""
|> String.replace("{the_element}", unquote(the_element))
end
end
defmacro is_show_on_mount(the_element, component_tag) do
quote do
attr(:is_show_on_mount, :boolean,
default: false,
doc:
"""
Displays {the_element} on mount without fade-in transition. Control conditional display by using Phoenix's `:if` attribute.
Example:
```
<{component_tag} is_show is_show_on_mount :if={@live_action in [:new, :edit]}>
...
</{component_tag}>
```
"""
|> String.replace("{the_element}", unquote(the_element))
|> String.replace("{component_tag}", unquote(component_tag))
)
end
end
defmacro on_cancel(the_element) do
quote do
attr :on_cancel, JS,
default: nil,
doc:
"""
`Phoenix.LiveView.JS` command to configure the closing/cancel event of {the_element}, for example: `on_cancel={JS.navigate(~p"/posts")}`.
"""
|> String.replace("{the_element}", unquote(the_element))
end
end
defmacro transition_duration(the_element, default_value) do
quote do
attr :transition_duration, :integer,
default: unquote(default_value),
doc:
"""
The number of milliseconds to fade-in/out {the_element}. Adds a CSS style attribute to {the_element} HTML.
"""
|> String.replace("{the_element}", unquote(the_element))
end
end
# Dialog and drawer specific
defmacro is_modal(the_element) do
quote do
attr :is_modal, :boolean,
default: false,
doc:
"""
Sets modal behavior: {the_element} can only be closed with Escape or by clicking a close button.
"""
|> String.replace("{the_element}", unquote(the_element))
end
end
defmacro is_escapable do
quote do
attr :is_escapable, :boolean,
default: true,
doc: """
Closes the content when the Escape key is pressed. Set to false to prevent this.
"""
end
end
defmacro focus_after_opening_selector(the_element) do
quote do
attr :focus_after_opening_selector, :string,
default: nil,
doc:
"""
By default, the first interactive element gets focus after opening {the_element}.
Use to set focus to a different element after opening. Pass the element selector.
"""
|> String.replace("{the_element}", unquote(the_element))
end
end
defmacro focus_after_closing_selector(the_element) do
quote do
attr :focus_after_closing_selector, :string,
default: nil,
doc:
"""
Returns focus to the specified element after closing {the_element}. Pass the element selector.
Improve accessibility by implementing this [ARIA Dialog Pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/).
"""
|> String.replace("{the_element}", unquote(the_element))
end
end
defmacro status_callback_selector(the_element) do
quote do
attr :status_callback_selector, :string,
default: nil,
doc:
"""
Receiver to get status callback events. Events are passed from the Prompt hook using `pushEventTo`.
Pass the HTML selector of the receiver of the LiveComponent or LiveView the element is defined in.
The event sends the object named "primer_live:prompt" with payload:
```
%{
"selector" => "", # callback selector
"elementId" => "", # {the_element} id
"status" => "" # possible values: "opening", "opened", "closing", "closed"
}
```
"""
|> String.replace("{the_element}", unquote(the_element))
end
end
end