Packages
livebook
0.8.1
0.19.8
0.19.7
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.6
0.18.5
0.18.4
0.18.3
0.18.2
0.18.1
0.18.0
0.17.3
0.17.2
0.17.1
0.17.0
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.7
0.14.6
0.14.5
0.14.4
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.3
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.3
0.9.2
0.9.1
0.9.0
0.8.2
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.3
0.6.2
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.3
0.2.2
0.2.1
0.2.0
0.1.2
0.1.1
0.1.0
Automate code & data workflows with interactive notebooks
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/livebook_web/live/form_helpers.ex
defmodule LivebookWeb.FormHelpers do
@moduledoc """
Conveniences for translating and building error messages.
"""
use Phoenix.Component
import Phoenix.HTML.Form
import LivebookWeb.LiveHelpers
@doc """
A wrapper for inputs with conveniences.
"""
def input_wrapper(assigns) do
assigns = assign_new(assigns, :class, fn -> [] end)
~H"""
<div
phx-feedback-for={input_name(@form, @field)}
class={[@class, if(@form.errors[@field], do: "show-errors", else: "")]}
>
<%= render_slot(@inner_block) %>
<%= for error <- Keyword.get_values(@form.errors, @field) do %>
<span class="hidden text-red-600 text-sm phx-form-error:block">
<%= translate_error(error) %>
</span>
<% end %>
</div>
"""
end
@doc """
Hex color input.
"""
def hex_color_input(assigns) do
~H"""
<div class="flex space-x-4 items-center">
<div
class="border-[3px] rounded-lg p-1 flex justify-center items-center"
style={"border-color: #{input_value(@form, @field)}"}
>
<div class="rounded h-5 w-5" style={"background-color: #{input_value(@form, @field)}"}></div>
</div>
<div class="relative grow">
<%= text_input(@form, @field,
class: "input",
spellcheck: "false",
maxlength: 7
) %>
<button class="icon-button absolute right-2 top-1" type="button" phx-click={@randomize}>
<.remix_icon icon="refresh-line" class="text-xl" />
</button>
</div>
</div>
"""
end
@doc """
Emoji input.
"""
def emoji_input(assigns) do
~H"""
<div id={@id} class="flex border-[1px] bg-gray-50 rounded-lg space-x-4 items-center">
<div id={"#{@id}-picker"} class="grid grid-cols-1 md:grid-cols-3 w-full" phx-hook="EmojiPicker">
<div class="place-content-start">
<div class="p-1 pl-3">
<span id={"#{@id}-preview"} data-emoji-preview><%= input_value(@form, @field) %></span>
</div>
</div>
<div />
<div class="flex items-center place-content-end">
<button
id={"#{@id}-button"}
type="button"
data-emoji-button
class="p-1 pl-3 pr-3 rounded-tr-lg rounded-br-lg bg-gray-50 hover:bg-gray-100 active:bg-gray-200 border-l-[1px] bg-white flex justify-center items-center cursor-pointer"
>
<.remix_icon icon="emotion-line" class="text-xl" />
</button>
</div>
<div id={"#{@id}-container"} data-emoji-container class="absolute mt-10 hidden" />
<%= hidden_input(@form, @field, class: "hidden emoji-picker-input", "data-emoji-input": true) %>
</div>
</div>
"""
end
@doc """
Translates an error message.
"""
def translate_error({msg, opts}) do
# Because the error messages we show in our forms and APIs
# are defined inside Ecto, we need to translate them dynamically.
Enum.reduce(opts, msg, fn {key, value}, acc ->
String.replace(acc, "%{#{key}}", fn _ -> to_string(value) end)
end)
end
end