mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-07 05:24:40 +08:00
* Added visibility toggle for password cell * Formatted code * Moved password toggle to separate component * Adjusted to review * Added password toggle for add filesystem component * Update lib/livebook_web/helpers.ex Co-authored-by: Jonatan Kłosko <jonatanklosko@gmail.com>
This commit is contained in:
parent
5f58fb902c
commit
ace64eab37
5 changed files with 95 additions and 5 deletions
|
@ -25,6 +25,7 @@ import MarkdownRenderer from "./markdown_renderer";
|
|||
import Highlight from "./highlight";
|
||||
import ClipCopy from "./clip_copy";
|
||||
import DragAndDrop from "./darg_and_drop";
|
||||
import PasswordToggle from "./password_toggle";
|
||||
import morphdomCallbacks from "./morphdom_callbacks";
|
||||
import { loadUserData } from "./lib/user";
|
||||
|
||||
|
@ -43,6 +44,7 @@ const hooks = {
|
|||
Highlight,
|
||||
ClipCopy,
|
||||
DragAndDrop,
|
||||
PasswordToggle,
|
||||
};
|
||||
|
||||
const csrfToken = document
|
||||
|
|
38
assets/js/password_toggle/index.js
Normal file
38
assets/js/password_toggle/index.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* A hook used to toggle password's input visibility via icon button.
|
||||
*/
|
||||
|
||||
const VISIBLE_ICON = "ri-eye-off-line";
|
||||
const OBSCURED_ICON = "ri-eye-line";
|
||||
|
||||
const PasswordToggle = {
|
||||
mounted() {
|
||||
this.visible = false;
|
||||
|
||||
this.input = this.el.querySelector("input");
|
||||
this.iconButton = this.el.querySelector("i");
|
||||
|
||||
this.iconButton.addEventListener("click", () => {
|
||||
this.visible = !this.visible;
|
||||
this._updateDOM();
|
||||
});
|
||||
},
|
||||
|
||||
updated() {
|
||||
this._updateDOM();
|
||||
},
|
||||
|
||||
_updateDOM() {
|
||||
if (this.visible) {
|
||||
this.input.type = "text";
|
||||
this.iconButton.classList.remove(OBSCURED_ICON);
|
||||
this.iconButton.classList.add(VISIBLE_ICON);
|
||||
} else {
|
||||
this.input.type = "password";
|
||||
this.iconButton.classList.remove(VISIBLE_ICON);
|
||||
this.iconButton.classList.add(OBSCURED_ICON);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default PasswordToggle;
|
|
@ -246,6 +246,35 @@ defmodule LivebookWeb.Helpers do
|
|||
"""
|
||||
end
|
||||
|
||||
@doc """
|
||||
Renders a wrapper around password input
|
||||
with an added visibility toggle button.
|
||||
|
||||
The toggle switches the input's type between `password`
|
||||
and `text`.
|
||||
|
||||
## Examples
|
||||
|
||||
<.with_password_toggle id="input-id">
|
||||
<input type="password" ...>
|
||||
</.with_password_toggle>
|
||||
"""
|
||||
def with_password_toggle(assigns) do
|
||||
~H"""
|
||||
<div id={"password-toggle-#{@id}"} class="relative inline w-min" phx-hook="PasswordToggle">
|
||||
<!-- render password input -->
|
||||
<%= render_block(@inner_block) %>
|
||||
<button
|
||||
class="bg-gray-50 p-1 icon-button absolute inset-y-0 right-1"
|
||||
type="button"
|
||||
aria-label="toggle password visibility"
|
||||
phx-change="ignore">
|
||||
<.remix_icon icon="eye-line" class="text-xl" />
|
||||
</button>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defdelegate ansi_string_to_html(string), to: LivebookWeb.Helpers.ANSI
|
||||
defdelegate ansi_string_to_html_lines(string), to: LivebookWeb.Helpers.ANSI
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
defmodule LivebookWeb.SessionLive.CellComponent do
|
||||
use LivebookWeb, :live_component
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="flex flex-col relative"
|
||||
|
@ -15,7 +16,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
def render_cell(%{cell_view: %{type: :markdown}} = assigns) do
|
||||
defp render_cell(%{cell_view: %{type: :markdown}} = assigns) do
|
||||
~H"""
|
||||
<div class="mb-1 flex items-center justify-end">
|
||||
<div class="relative z-20 flex items-center justify-end space-x-2" data-element="actions">
|
||||
|
@ -51,7 +52,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
def render_cell(%{cell_view: %{type: :elixir}} = assigns) do
|
||||
defp render_cell(%{cell_view: %{type: :elixir}} = assigns) do
|
||||
~H"""
|
||||
<div class="mb-1 flex items-center justify-between">
|
||||
<div class="relative z-20 flex items-center justify-end space-x-2" data-element="actions" data-primary>
|
||||
|
@ -106,7 +107,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
def render_cell(%{cell_view: %{type: :input}} = assigns) do
|
||||
defp render_cell(%{cell_view: %{type: :input}} = assigns) do
|
||||
~H"""
|
||||
<div class="mb-1 flex items-center justify-end">
|
||||
<div class="relative z-20 flex items-center justify-end space-x-2" data-element="actions">
|
||||
|
@ -200,6 +201,22 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
"""
|
||||
end
|
||||
|
||||
defp cell_input(%{cell_view: %{input_type: :password}} = assigns) do
|
||||
~H"""
|
||||
<.with_password_toggle id={@cell_view.id}>
|
||||
<input type="password"
|
||||
data-element="input"
|
||||
class={"input w-auto bg-gray-50 #{if(@cell_view.error, do: "input--error")}"}
|
||||
name="value"
|
||||
value={@cell_view.value}
|
||||
phx-debounce="300"
|
||||
spellcheck="false"
|
||||
autocomplete="off"
|
||||
tabindex="-1" />
|
||||
</.with_password_toggle>
|
||||
"""
|
||||
end
|
||||
|
||||
defp cell_input(assigns) do
|
||||
~H"""
|
||||
<input type={html_input_type(@cell_view.input_type)}
|
||||
|
|
|
@ -46,11 +46,15 @@ defmodule LivebookWeb.SettingsLive.AddFileSystemComponent do
|
|||
</div>
|
||||
<div>
|
||||
<div class="input-label">Access Key ID</div>
|
||||
<%= text_input f, :access_key_id, value: @data["access_key_id"], class: "input", type: "password" %>
|
||||
<.with_password_toggle id="access-key">
|
||||
<%= text_input f, :access_key_id, value: @data["access_key_id"], class: "input", type: "password" %>
|
||||
</.with_password_toggle>
|
||||
</div>
|
||||
<div>
|
||||
<div class="input-label">Secret Access Key</div>
|
||||
<%= text_input f, :secret_access_key, value: @data["secret_access_key"], class: "input", type: "password" %>
|
||||
<.with_password_toggle id="secret-access-key">
|
||||
<%= text_input f, :secret_access_key, value: @data["secret_access_key"], class: "input", type: "password" %>
|
||||
</.with_password_toggle>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 flex justify-end space-x-2">
|
||||
|
|
Loading…
Add table
Reference in a new issue