mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-09-04 12:04:20 +08:00
Improve icon buttons accessibility and navigation (#667)
* Rename tooltip source attribute * Add aria-label to icon buttons/links * Actually focus cell content when navigating around * Add some descriptions * Fix dynamically computed tooltips
This commit is contained in:
parent
03842d8cd1
commit
021d6ac42e
17 changed files with 106 additions and 67 deletions
|
@ -3,7 +3,7 @@
|
|||
/*
|
||||
Example usage:
|
||||
|
||||
<span class="tooltip top" aria-label="Delete">
|
||||
<span class="tooltip top" data-tooltip="Delete">
|
||||
...
|
||||
</span>
|
||||
*/
|
||||
|
@ -28,7 +28,7 @@ Example usage:
|
|||
/* Tooltip text */
|
||||
.tooltip:before {
|
||||
position: absolute;
|
||||
content: attr(aria-label);
|
||||
content: attr(data-tooltip);
|
||||
white-space: pre;
|
||||
text-align: center;
|
||||
display: block;
|
||||
|
|
|
@ -728,6 +728,9 @@ function setFocusedCell(hook, cellId, scroll = true) {
|
|||
hook.state.focusedSectionId = getSectionIdByCellId(
|
||||
hook.state.focusedCellId
|
||||
);
|
||||
// Focus the primary cell content, this is important for screen readers
|
||||
const cellBody = cell.querySelector(`[data-element="cell-body"]`);
|
||||
cellBody.focus();
|
||||
} else {
|
||||
hook.state.focusedCellType = null;
|
||||
hook.state.focusedSectionId = null;
|
||||
|
|
|
@ -110,7 +110,7 @@ defmodule LivebookWeb.Helpers do
|
|||
|> assign(:attrs, assigns_to_attributes(assigns, [:icon, :class]))
|
||||
|
||||
~H"""
|
||||
<i class={"ri-#{@icon} #{@class}"} {@attrs}></i>
|
||||
<i class={"ri-#{@icon} #{@class}"} aria-hidden="true" {@attrs}></i>
|
||||
"""
|
||||
end
|
||||
|
||||
|
|
|
@ -147,7 +147,7 @@ defmodule LivebookWeb.HomeLive do
|
|||
|
||||
defp open_button_tooltip_attrs(file, file_info) do
|
||||
if regular?(file, file_info) and not writable?(file_info) do
|
||||
[class: "tooltip top", aria_label: "This file is write-protected, please fork instead"]
|
||||
[class: "tooltip top", data_tooltip: "This file is write-protected, please fork instead"]
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
|
|
@ -51,8 +51,8 @@ defmodule LivebookWeb.Output.TableDynamicLive do
|
|||
<!-- Actions -->
|
||||
<div class="flex space-x-2">
|
||||
<%= if :refetch in @features do %>
|
||||
<span class="tooltip left" aria-label="Refetch">
|
||||
<button class="icon-button" phx-click="refetch">
|
||||
<span class="tooltip left" data-tooltip="Refetch">
|
||||
<button class="icon-button" aria-label="refresh" phx-click="refetch">
|
||||
<.remix_icon icon="refresh-line" class="text-xl" />
|
||||
</button>
|
||||
</span>
|
||||
|
|
|
@ -170,17 +170,17 @@ defmodule LivebookWeb.SessionLive do
|
|||
<span><%= user.name || "Anonymous" %></span>
|
||||
</button>
|
||||
<%= if client_pid != @self do %>
|
||||
<span class="tooltip left" aria-label="Follow this user"
|
||||
<span class="tooltip left" data-tooltip="Follow this user"
|
||||
data-element="client-follow-toggle"
|
||||
data-meta="follow">
|
||||
<button class="icon-button">
|
||||
<button class="icon-button" aria-label="follow this user">
|
||||
<.remix_icon icon="pushpin-line" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip left" aria-label="Unfollow this user"
|
||||
<span class="tooltip left" data-tooltip="Unfollow this user"
|
||||
data-element="client-follow-toggle"
|
||||
data-meta="unfollow">
|
||||
<button class="icon-button">
|
||||
<button class="icon-button" aria-label="unfollow this user">
|
||||
<.remix_icon icon="pushpin-fill" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
|
@ -195,6 +195,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
<div class="w-full max-w-screen-lg px-16 mx-auto py-7">
|
||||
<div class="flex items-center pb-4 mb-6 space-x-4 border-b border-gray-200">
|
||||
<h1 class="flex-grow p-1 -ml-1 text-3xl font-semibold text-gray-800 border border-transparent rounded-lg hover:border-blue-200 focus:border-blue-300"
|
||||
aria-description="notebook title"
|
||||
id="notebook-name"
|
||||
data-element="notebook-name"
|
||||
contenteditable
|
||||
|
@ -402,7 +403,7 @@ defmodule LivebookWeb.SessionLive do
|
|||
wrapped_name = Livebook.Utils.wrap_line("”" <> parent_name <> "”", 16)
|
||||
label = "Branches from\n#{wrapped_name}"
|
||||
|
||||
[class: "tooltip #{direction}", "aria-label": label]
|
||||
[class: "tooltip #{direction}", data_tooltip: label]
|
||||
end
|
||||
|
||||
@impl true
|
||||
|
|
|
@ -70,16 +70,18 @@ defmodule LivebookWeb.SessionLive.BinComponent do
|
|||
<span class="font-semibold"><%= format_date_relatively(entry.deleted_at) %></span>
|
||||
</p>
|
||||
<div class="flex justify-end space-x-2">
|
||||
<span class="tooltip left" aria-label="Copy source">
|
||||
<span class="tooltip left" data-tooltip="Copy source">
|
||||
<button class="icon-button"
|
||||
aria-label="copy source"
|
||||
id={"bin-cell-#{cell.id}-clipcopy"}
|
||||
phx-hook="ClipCopy"
|
||||
data-target-id={"bin-cell-#{cell.id}-source"}>
|
||||
<.remix_icon icon="clipboard-line" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip left" aria-label="Restore">
|
||||
<span class="tooltip left" data-tooltip="Restore">
|
||||
<button class="icon-button"
|
||||
aria-label="restore"
|
||||
phx-click="restore"
|
||||
phx-value-cell_id={entry.cell.id}
|
||||
phx-target={@myself}>
|
||||
|
|
|
@ -21,14 +21,15 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
<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">
|
||||
<.cell_link_button cell_id={@cell_view.id} />
|
||||
<span class="tooltip top" aria-label="Edit content" data-element="enable-insert-mode-button">
|
||||
<button class="icon-button">
|
||||
<span class="tooltip top" data-tooltip="Edit content" data-element="enable-insert-mode-button">
|
||||
<button class="icon-button" aria-label="edit content">
|
||||
<.remix_icon icon="pencil-line" class="text-xl" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip top" aria-label="Insert image" data-element="insert-image-button">
|
||||
<span class="tooltip top" data-tooltip="Insert image" data-element="insert-image-button">
|
||||
<%= live_patch to: Routes.session_path(@socket, :cell_upload, @session_id, @cell_view.id),
|
||||
class: "icon-button" do %>
|
||||
class: "icon-button",
|
||||
aria_label: "insert image" do %>
|
||||
<.remix_icon icon="image-add-line" class="text-xl" />
|
||||
<% end %>
|
||||
</span>
|
||||
|
@ -240,7 +241,8 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp cell_body(assigns) do
|
||||
~H"""
|
||||
<div class="flex relative">
|
||||
<!-- By setting tabindex="-1" we can programmatically focus this element -->
|
||||
<div class="flex relative" data-element="cell-body" tabindex="-1">
|
||||
<div class="w-1 h-full rounded-lg absolute top-0 -left-3" data-element="cell-focus-indicator">
|
||||
</div>
|
||||
<div class="w-full">
|
||||
|
@ -252,8 +254,8 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp cell_link_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" aria-label="Link">
|
||||
<a href={"#cell-#{@cell_id}"} class="icon-button">
|
||||
<span class="tooltip top" data-tooltip="Link">
|
||||
<a href={"#cell-#{@cell_id}"} class="icon-button" aria-label="link to cell">
|
||||
<.remix_icon icon="link" class="text-xl" />
|
||||
</a>
|
||||
</span>
|
||||
|
@ -262,8 +264,10 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp cell_settings_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" aria-label="Cell settings">
|
||||
<%= live_patch to: Routes.session_path(@socket, :cell_settings, @session_id, @cell_id), class: "icon-button" do %>
|
||||
<span class="tooltip top" data-tooltip="Cell settings">
|
||||
<%= live_patch to: Routes.session_path(@socket, :cell_settings, @session_id, @cell_id),
|
||||
class: "icon-button",
|
||||
aria_label: "cell settings" do %>
|
||||
<.remix_icon icon="settings-3-line" class="text-xl" />
|
||||
<% end %>
|
||||
</span>
|
||||
|
@ -272,8 +276,9 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp move_cell_up_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" aria-label="Move up">
|
||||
<span class="tooltip top" data-tooltip="Move up">
|
||||
<button class="icon-button"
|
||||
aria-label="move cell up"
|
||||
phx-click="move_cell"
|
||||
phx-value-cell_id={@cell_id}
|
||||
phx-value-offset="-1">
|
||||
|
@ -285,8 +290,9 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp move_cell_down_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" aria-label="Move down">
|
||||
<span class="tooltip top" data-tooltip="Move down">
|
||||
<button class="icon-button"
|
||||
aria-label="move cell down"
|
||||
phx-click="move_cell"
|
||||
phx-value-cell_id={@cell_id}
|
||||
phx-value-offset="1">
|
||||
|
@ -298,8 +304,9 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|
||||
defp delete_cell_button(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip top" aria-label="Delete">
|
||||
<span class="tooltip top" data-tooltip="Delete">
|
||||
<button class="icon-button"
|
||||
aria-label="delete cell"
|
||||
phx-click="delete_cell"
|
||||
phx-value-cell_id={@cell_id}>
|
||||
<.remix_icon icon="delete-bin-6-line" class="text-xl" />
|
||||
|
@ -406,7 +413,7 @@ defmodule LivebookWeb.SessionLive.CellComponent do
|
|||
|> assign_new(:tooltip, fn -> nil end)
|
||||
|
||||
~H"""
|
||||
<div class={"#{if(@tooltip, do: "tooltip")} bottom distant-medium"} aria-label={@tooltip}>
|
||||
<div class={"#{if(@tooltip, do: "tooltip")} bottom distant-medium"} data-tooltip={@tooltip}>
|
||||
<div class="flex items-center space-x-1">
|
||||
<div class="flex text-xs text-gray-400">
|
||||
<%= render_block(@inner_block) %>
|
||||
|
|
|
@ -31,16 +31,18 @@ defmodule LivebookWeb.SessionLive.ExportElixirComponent do
|
|||
.exs
|
||||
</span>
|
||||
<div class="flex justify-end space-x-2">
|
||||
<span class="tooltip left" aria-label="Copy source">
|
||||
<span class="tooltip left" data-tooltip="Copy source">
|
||||
<button class="icon-button"
|
||||
aria-label="copy source"
|
||||
id="export-notebook-source-clipcopy"
|
||||
phx-hook="ClipCopy"
|
||||
data-target-id="export-notebook-source">
|
||||
<.remix_icon icon="clipboard-line" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip left" aria-label="Download source">
|
||||
<span class="tooltip left" data-tooltip="Download source">
|
||||
<a class="icon-button"
|
||||
aria-label="download source"
|
||||
href={Routes.session_path(@socket, :download_source, @session.id, "exs")}>
|
||||
<.remix_icon icon="download-2-line" class="text-lg" />
|
||||
</a>
|
||||
|
|
|
@ -38,16 +38,18 @@ defmodule LivebookWeb.SessionLive.ExportLiveMarkdownComponent do
|
|||
.livemd
|
||||
</span>
|
||||
<div class="flex justify-end space-x-2">
|
||||
<span class="tooltip left" aria-label="Copy source">
|
||||
<span class="tooltip left" data-tooltip="Copy source">
|
||||
<button class="icon-button"
|
||||
aria-label="copy source"
|
||||
id="export-notebook-source-clipcopy"
|
||||
phx-hook="ClipCopy"
|
||||
data-target-id="export-notebook-source">
|
||||
<.remix_icon icon="clipboard-line" class="text-lg" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip left" aria-label="Download source">
|
||||
<span class="tooltip left" data-tooltip="Download source">
|
||||
<a class="icon-button"
|
||||
aria-label="download source"
|
||||
href={Routes.session_path(@socket, :download_source, @session.id, "livemd", include_outputs: @include_outputs)}>
|
||||
<.remix_icon icon="download-2-line" class="text-lg" />
|
||||
</a>
|
||||
|
|
|
@ -8,32 +8,36 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
<%= if @file do %>
|
||||
<%= if @dirty do %>
|
||||
<%= if @autosave_interval_s do %>
|
||||
<span class="tooltip left" aria-label="Autosave pending">
|
||||
<span class="tooltip left" data-tooltip="Autosave pending">
|
||||
<%= live_patch to: Routes.session_path(@socket, :file_settings, @session_id),
|
||||
class: "icon-button icon-outlined-button border-blue-400 hover:bg-blue-50 focus:bg-blue-50" do %>
|
||||
class: "icon-button icon-outlined-button border-blue-400 hover:bg-blue-50 focus:bg-blue-50",
|
||||
aria_label: "autosave pending, click to open file settings" do %>
|
||||
<.remix_icon icon="save-line" class="text-xl text-blue-500" />
|
||||
<% end %>
|
||||
</span>
|
||||
<% else %>
|
||||
<span class="tooltip left" aria-label="No autosave configured, make sure to save manually">
|
||||
<span class="tooltip left" data-tooltip="No autosave configured, make sure to save manually">
|
||||
<%= live_patch to: Routes.session_path(@socket, :file_settings, @session_id),
|
||||
class: "icon-button icon-outlined-button border-yellow-200 hover:bg-red-50 focus:bg-red-50" do %>
|
||||
class: "icon-button icon-outlined-button border-yellow-200 hover:bg-red-50 focus:bg-red-50",
|
||||
aria_label: "no autosave configured, click to open file settings" do %>
|
||||
<.remix_icon icon="save-line" class="text-xl text-yellow-300" />
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<span class="tooltip left" aria-label="Notebook saved">
|
||||
<span class="tooltip left" data-tooltip="Notebook saved">
|
||||
<%= live_patch to: Routes.session_path(@socket, :file_settings, @session_id),
|
||||
class: "icon-button icon-outlined-button border-green-300 hover:bg-green-50 focus:bg-green-50" do %>
|
||||
class: "icon-button icon-outlined-button border-green-300 hover:bg-green-50 focus:bg-green-50",
|
||||
aria_label: "notebook saved, click to open file settings" do %>
|
||||
<.remix_icon icon="save-line" class="text-xl text-green-400" />
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<span class="tooltip left" aria-label="Choose a file to save the notebook">
|
||||
<span class="tooltip left" data-tooltip="Choose a file to save the notebook">
|
||||
<%= live_patch to: Routes.session_path(@socket, :file_settings, @session_id),
|
||||
class: "icon-button icon-outlined-button border-gray-200 hover:bg-gray-100 focus:bg-gray-100" do %>
|
||||
class: "icon-button icon-outlined-button border-gray-200 hover:bg-gray-100 focus:bg-gray-100",
|
||||
aria_label: "choose a file to save the notebook" do %>
|
||||
<.remix_icon icon="save-line" class="text-xl text-gray-400" />
|
||||
<% end %>
|
||||
</span>
|
||||
|
@ -44,16 +48,17 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
status={elem(@global_status, 0)}
|
||||
cell_id={elem(@global_status, 1)} />
|
||||
<% else %>
|
||||
<span class="tooltip left" aria-label="Choose a runtime to run the notebook in">
|
||||
<span class="tooltip left" data-tooltip="Choose a runtime to run the notebook in">
|
||||
<%= live_patch to: Routes.session_path(@socket, :runtime_settings, @session_id),
|
||||
class: "icon-button icon-outlined-button border-gray-200 hover:bg-gray-100 focus:bg-gray-100" do %>
|
||||
class: "icon-button icon-outlined-button border-gray-200 hover:bg-gray-100 focus:bg-gray-100",
|
||||
aria_label: "choose a runtime to run the notebook in" do %>
|
||||
<.remix_icon icon="loader-3-line" class="text-xl text-gray-400" />
|
||||
<% end %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<%# Note: this indicator is shown/hidden using CSS based on the current mode %>
|
||||
<span class="tooltip left" aria-label="Insert mode" data-element="insert-mode-indicator">
|
||||
<span class="tooltip left" data-tooltip="Insert mode" data-element="insert-mode-indicator">
|
||||
<span class="text-sm font-medium text-gray-400 cursor-default">
|
||||
ins
|
||||
</span>
|
||||
|
@ -64,8 +69,9 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
|
||||
defp global_status(%{status: :evaluating} = assigns) do
|
||||
~H"""
|
||||
<span class="tooltip left" aria-label="Go to evaluating cell">
|
||||
<span class="tooltip left" data-tooltip="Go to evaluating cell">
|
||||
<button class="border-blue-400 icon-button icon-outlined-button hover:bg-blue-50 focus:bg-blue-50"
|
||||
aria-label="go to evaluating cell"
|
||||
data-element="focus-cell-button"
|
||||
data-target={@cell_id}>
|
||||
<.remix_icon icon="loader-3-line" class="text-xl text-blue-500 animate-spin" />
|
||||
|
@ -76,8 +82,9 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
|
||||
defp global_status(%{status: :evaluated} = assigns) do
|
||||
~H"""
|
||||
<span class="tooltip left" aria-label="Go to last evaluated cell">
|
||||
<span class="tooltip left" data-tooltip="Go to last evaluated cell">
|
||||
<button class="border-green-300 icon-button icon-outlined-button hover:bg-green-50 focus:bg-green-50"
|
||||
aria-label="go to last evaluated cell"
|
||||
data-element="focus-cell-button"
|
||||
data-target={@cell_id}>
|
||||
<.remix_icon icon="loader-3-line" class="text-xl text-green-400" />
|
||||
|
@ -88,8 +95,9 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
|
||||
defp global_status(%{status: :stale} = assigns) do
|
||||
~H"""
|
||||
<span class="tooltip left" aria-label="Go to first stale cell">
|
||||
<span class="tooltip left" data-tooltip="Go to first stale cell">
|
||||
<button class="border-yellow-200 icon-button icon-outlined-button hover:bg-yellow-50 focus:bg-yellow-50"
|
||||
aria-label="go to first stale cell"
|
||||
data-element="focus-cell-button"
|
||||
data-target={@cell_id}>
|
||||
<.remix_icon icon="loader-3-line" class="text-xl text-yellow-300" />
|
||||
|
@ -100,10 +108,11 @@ defmodule LivebookWeb.SessionLive.IndicatorsComponent do
|
|||
|
||||
defp global_status(%{status: :fresh} = assigns) do
|
||||
~H"""
|
||||
<span class="tooltip left" aria-label="Ready to evaluate">
|
||||
<button class="border-gray-200 cursor-default icon-button icon-outlined-button hover:bg-gray-100 focus:bg-gray-100">
|
||||
<span class="tooltip left" data-tooltip="Ready to evaluate">
|
||||
<div class="border-gray-200 icon-button icon-outlined-button hover:bg-gray-100 focus:bg-gray-100"
|
||||
aria-label="ready to evaluate">
|
||||
<.remix_icon icon="loader-3-line" class="text-xl text-gray-400" />
|
||||
</button>
|
||||
</div>
|
||||
</span>
|
||||
"""
|
||||
end
|
||||
|
|
|
@ -71,7 +71,7 @@ defmodule LivebookWeb.SessionLive.PersistenceLive do
|
|||
<div class="flex space-x-2 items-center">
|
||||
<span class="text-gray-700 whitespace-nowrap">File:</span>
|
||||
<%= if @new_attrs.file do %>
|
||||
<span class="tooltip right" aria-label={file_system_label(@new_attrs.file.file_system)}>
|
||||
<span class="tooltip right" data-tooltip={file_system_label(@new_attrs.file.file_system)}>
|
||||
<span class="flex items-center">
|
||||
[<.file_system_icon file_system={@new_attrs.file.file_system} />]
|
||||
</span>
|
||||
|
|
|
@ -7,6 +7,7 @@ defmodule LivebookWeb.SessionLive.SectionComponent do
|
|||
<div class="flex space-x-4 items-center" data-element="section-headline">
|
||||
<h2 class="flex-grow text-gray-800 font-semibold text-2xl px-1 -ml-1 rounded-lg border
|
||||
border-transparent hover:border-blue-200 focus:border-blue-300"
|
||||
aria-description="section title"
|
||||
data-element="section-name"
|
||||
id={@section_view.html_id}
|
||||
contenteditable
|
||||
|
@ -18,15 +19,17 @@ defmodule LivebookWeb.SessionLive.SectionComponent do
|
|||
<%# ^ Note it's important there's no space between <h2> and </h2>
|
||||
because we want the content to exactly match section name. %>
|
||||
<div class="flex space-x-2 items-center" data-element="section-actions">
|
||||
<span class="tooltip top" aria-label="Link">
|
||||
<a href={"##{@section_view.html_id}"} class="icon-button">
|
||||
<span class="tooltip top" data-tooltip="Link">
|
||||
<a href={"##{@section_view.html_id}"} class="icon-button" aria-label="link to section">
|
||||
<.remix_icon icon="link" class="text-xl" />
|
||||
</a>
|
||||
</span>
|
||||
<%= if @section_view.valid_parents != [] and not @section_view.has_children? do %>
|
||||
<div class="relative" id={"section-#{@section_view.id}-branch-menu"} phx-hook="Menu" data-element="menu">
|
||||
<span class="tooltip top" aria-label="Branch out from">
|
||||
<button class="icon-button" data-toggle>
|
||||
<span class="tooltip top" data-tooltip="Branch out from">
|
||||
<button class="icon-button"
|
||||
aria-label="branch out from other section"
|
||||
data-toggle>
|
||||
<.remix_icon icon="git-branch-line" class="text-xl flip-horizontally" />
|
||||
</button>
|
||||
</span>
|
||||
|
@ -52,25 +55,28 @@ defmodule LivebookWeb.SessionLive.SectionComponent do
|
|||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<span class="tooltip top" aria-label="Move up">
|
||||
<span class="tooltip top" data-tooltip="Move up">
|
||||
<button class="icon-button"
|
||||
aria-label="move section up"
|
||||
phx-click="move_section"
|
||||
phx-value-section_id={@section_view.id}
|
||||
phx-value-offset="-1">
|
||||
<.remix_icon icon="arrow-up-s-line" class="text-xl" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip top" aria-label="Move down">
|
||||
<span class="tooltip top" data-tooltip="Move down">
|
||||
<button class="icon-button"
|
||||
aria-label="move section down"
|
||||
phx-click="move_section"
|
||||
phx-value-section_id={@section_view.id}
|
||||
phx-value-offset="1">
|
||||
<.remix_icon icon="arrow-down-s-line" class="text-xl" />
|
||||
</button>
|
||||
</span>
|
||||
<span class="tooltip top" aria-label={if @section_view.has_children?, do: "Cannot delete this section because\nother sections branch from it", else: "Delete"}>
|
||||
<span class="tooltip top" data-tooltip={if @section_view.has_children?, do: "Cannot delete this section because\nother sections branch from it", else: "Delete"}>
|
||||
<%= live_patch to: Routes.session_path(@socket, :delete_section, @session_id, @section_view.id),
|
||||
class: "icon-button #{if @section_view.has_children?, do: "disabled"}" do %>
|
||||
class: "icon-button #{if @section_view.has_children?, do: "disabled"}",
|
||||
aria_label: "delete section" do %>
|
||||
<.remix_icon icon="delete-bin-6-line" class="text-xl" />
|
||||
<% end %>
|
||||
</span>
|
||||
|
@ -78,7 +84,7 @@ defmodule LivebookWeb.SessionLive.SectionComponent do
|
|||
</div>
|
||||
<%= if @section_view.parent do %>
|
||||
<h3 class="mt-1 flex items-end space-x-1 text-sm font-semibold text-gray-800">
|
||||
<span class="tooltip bottom" aria-label={"This section branches out from the main flow\nand can be evaluated in parallel"}>
|
||||
<span class="tooltip bottom" data-tooltip={"This section branches out from the main flow\nand can be evaluated in parallel"}>
|
||||
<.remix_icon icon="git-branch-line" class="text-lg font-normal flip-horizontally leading-none" />
|
||||
</span>
|
||||
<span class="leading-none">from ”<%= @section_view.parent.name %>”</span>
|
||||
|
|
|
@ -54,8 +54,9 @@ defmodule LivebookWeb.SettingsLive do
|
|||
<h2 class="text-xl text-gray-800 font-semibold">
|
||||
File systems
|
||||
</h2>
|
||||
<span class="tooltip top" aria-label="Copy as environment variables">
|
||||
<span class="tooltip top" data-tooltip="Copy as environment variables">
|
||||
<button class="icon-button"
|
||||
aria-label="copy as environment variables"
|
||||
id={"file-systems-env-clipcopy"}
|
||||
phx-hook="ClipCopy"
|
||||
data-target-id={"file-systems-env-source"}
|
||||
|
|
|
@ -23,8 +23,8 @@ defmodule LivebookWeb.SidebarHelpers do
|
|||
def logo_item(assigns) do
|
||||
~H"""
|
||||
<span>
|
||||
<%= live_patch to: Routes.home_path(@socket, :page) do %>
|
||||
<img src="/images/logo.png" height="40" width="40" alt="livebook" />
|
||||
<%= live_patch to: Routes.home_path(@socket, :page), aria_label: "go to homepage" do %>
|
||||
<img src="/images/logo.png" height="40" width="40" alt="" />
|
||||
<% end %>
|
||||
</span>
|
||||
"""
|
||||
|
@ -32,8 +32,9 @@ defmodule LivebookWeb.SidebarHelpers do
|
|||
|
||||
def button_item(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip right distant" aria-label={@label}>
|
||||
<span class="tooltip right distant" data-tooltip={@label}>
|
||||
<button class="text-2xl text-gray-400 hover:text-gray-50 focus:text-gray-50 rounded-xl h-10 w-10 flex items-center justify-center"
|
||||
aria-label={@label}
|
||||
data-element={@data_element}>
|
||||
<.remix_icon icon={@icon} />
|
||||
</button>
|
||||
|
@ -43,9 +44,10 @@ defmodule LivebookWeb.SidebarHelpers do
|
|||
|
||||
def link_item(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip right distant" aria-label={@label}>
|
||||
<span class="tooltip right distant" data-tooltip={@label}>
|
||||
<%= live_patch to: @path,
|
||||
class: "text-gray-400 hover:text-gray-50 focus:text-gray-50 rounded-xl h-10 w-10 flex items-center justify-center #{if(@active, do: "text-gray-50 bg-gray-700")}" do %>
|
||||
class: "text-gray-400 hover:text-gray-50 focus:text-gray-50 rounded-xl h-10 w-10 flex items-center justify-center #{if(@active, do: "text-gray-50 bg-gray-700")}",
|
||||
aria_label: @label do %>
|
||||
<.remix_icon icon={@icon} class="text-2xl" />
|
||||
<% end %>
|
||||
</span>
|
||||
|
@ -60,8 +62,10 @@ defmodule LivebookWeb.SidebarHelpers do
|
|||
|
||||
def user_item(assigns) do
|
||||
~H"""
|
||||
<span class="tooltip right distant" aria-label="User profile">
|
||||
<%= live_patch to: @path, class: "text-gray-400 rounded-xl h-8 w-8 flex items-center justify-center" do %>
|
||||
<span class="tooltip right distant" data-tooltip="User profile">
|
||||
<%= live_patch to: @path,
|
||||
class: "text-gray-400 rounded-xl h-8 w-8 flex items-center justify-center",
|
||||
aria_label: "user profile" do %>
|
||||
<.user_avatar user={@current_user} text_class="text-xs" />
|
||||
<% end %>
|
||||
</span>
|
||||
|
|
|
@ -17,7 +17,9 @@ defmodule LivebookWeb.UserHelpers do
|
|||
|> assign_new(:text_class, fn -> "" end)
|
||||
|
||||
~H"""
|
||||
<div class={"#{@class} rounded-full flex items-center justify-center"} style={"background-color: #{@user.hex_color}"}>
|
||||
<div class={"#{@class} rounded-full flex items-center justify-center"}
|
||||
style={"background-color: #{@user.hex_color}"}
|
||||
aria-hidden="true">
|
||||
<div class={"#{@text_class} text-gray-100 font-semibold"}>
|
||||
<%= avatar_text(@user.name) %>
|
||||
</div>
|
||||
|
|
|
@ -106,7 +106,7 @@ defmodule LivebookWeb.HomeLiveTest do
|
|||
|> has_element?()
|
||||
|
||||
assert view
|
||||
|> element(~s{[aria-label="This file is write-protected, please fork instead"]})
|
||||
|> element(~s{[data-tooltip="This file is write-protected, please fork instead"]})
|
||||
|> has_element?()
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue