Merge pull request #1156 from basecamp/tooltip-orient

Tooltip orient
This commit is contained in:
Andy Smith
2025-09-29 14:11:04 -05:00
committed by GitHub
15 changed files with 69 additions and 20 deletions
+1
View File
@@ -80,6 +80,7 @@
--z-popup: 10;
--z-terminal: 20;
--z-tray: 21;
--z-tooltip: 30;
/* OKLCH colors: Fixed */
--lch-black: 0% 0 0;
+20 -4
View File
@@ -1,5 +1,5 @@
@layer components {
.tooltip {
[data-controller^="tooltip"] {
--tooltip-delay: 750ms;
--tooltip-duration: 150ms;
@@ -10,13 +10,23 @@
font-size: var(--text-x-small);
font-weight: normal;
inset: -1ch auto auto 50%;
max-inline-size: 28ch;
max-inline-size: 50ch;
opacity: 0;
padding: 0.25ch 1ch;
transition: var(--tooltip-duration) ease-out allow-discrete;
transition-property: opacity, translate;
translate: -50% -85%;
transition-property: opacity;
translate: -50% -100%;
text-overflow: ellipsis;
&.orient-right {
inset-inline-start: 0;
translate: 0 -100%;
}
&.orient-left {
inset-inline-end: 0;
translate: 0 -100%;
}
}
@media(any-hover: hover) {
@@ -27,6 +37,12 @@
opacity: 1;
transition-delay: var(--tooltip-delay);
translate: -50% -100%;
z-index: var(--z-tooltip);
&.orient-left,
&.orient-right {
translate: 0 -100%;
}
}
}
}
@@ -0,0 +1,32 @@
import { Controller } from "@hotwired/stimulus"
import { orient } from "helpers/orientation_helpers"
export default class extends Controller {
static targets = [ "tooltip" ]
connect() {
this.element.addEventListener("mouseenter", this.mouseEnter.bind(this))
this.element.addEventListener("mouseout", this.mouseOut.bind(this))
}
disconnect() {
this.element.removeEventListener("mouseenter", this.mouseEnter.bind(this))
this.element.removeEventListener("mouseout", this.mouseOut.bind(this))
}
mouseEnter(event) {
orient(this.#tooltipElement)
}
mouseOut(event) {
orient(this.#tooltipElement, false)
}
get #tooltipElement() {
return this.element.querySelector(".for-screen-reader")
}
get #tooltipText() {
return this.#tooltipElement.innerText
}
}
@@ -1,4 +1,4 @@
<%= link_to edit_collection_path(collection), class: "btn tooltip" do %>
<%= link_to edit_collection_path(collection), class: "btn", data: { controller: "tooltip" } do %>
<%= icon_tag "settings" %>
<span class="for-screen-reader">Settings for <%= collection.name %></span>
<% end %>
+1 -1
View File
@@ -1,4 +1,4 @@
<%= link_to collection_webhooks_path(collection_id: collection), class: ["btn tooltip", {"btn--reversed": collection.webhooks.any?}] do %>
<%= link_to collection_webhooks_path(collection_id: collection), class: ["btn", {"btn--reversed": collection.webhooks.any?}], data: { controller: "tooltip" } do %>
<%= icon_tag "world" %>
<span class="for-screen-reader">Webhooks</span>
<% end %>
+2 -2
View File
@@ -1,10 +1,10 @@
<% if card.golden? %>
<%= button_to card_goldness_path(card), method: :delete, class: "btn btn--reversed tooltip" do %>
<%= button_to card_goldness_path(card), method: :delete, class: "btn btn--reversed", data: { controller: "tooltip" } do %>
<%= icon_tag "golden-ticket" %>
<span class="for-screen-reader">Demote to normal</span>
<% end %>
<% else %>
<%= button_to card_goldness_path(card), class: "btn tooltip" do %>
<%= button_to card_goldness_path(card), class: "btn", data: { controller: "tooltip" } do %>
<%= icon_tag "golden-ticket" %>
<span class="for-screen-reader">Promote to golden</span>
<% end %>
+2 -2
View File
@@ -1,11 +1,11 @@
<% if card.image.attached? %>
<%= button_to card_image_path(card), method: :delete, class: "btn tooltip" do %>
<%= button_to card_image_path(card), method: :delete, class: "btn", data: { controller: "tooltip" } do %>
<%= icon_tag "picture-remove" %>
<span class="for-screen-reader">Remove background image</span>
<% end %>
<% elsif !card.closed? %>
<%= form_with model: card, url: card_path(card), data: { controller: "form" } do |form| %>
<label class="btn input--file tooltip">
<label class="btn input--file" data-controller="tooltip">
<%= icon_tag "picture-add" %>
<span class="for-screen-reader">Add background image</span>
<%= form.file_field :image, class: "input",
@@ -1,6 +1,6 @@
<div class="card-perma__notch card-perma__notch--bottom">
<%= button_to "Create card", card_publish_path(card), name: "creation_type", value: "add", class: "btn" %>
<%= button_to "Create and add another", card_publish_path(card), method: :post, class: "btn btn--reversed tooltip", name: "creation_type", value: "add_another",
<%= button_to "Create and add another", card_publish_path(card), method: :post, class: "btn btn--reversed", name: "creation_type", value: "add_another",
title: "Create and add another (ctrl+shift+enter)", form: { data: { turbo: false } }, data: { controller: "hotkey", action: "keydown.ctrl+shift+enter@document->hotkey#click" } %>
<%= button_to "Save as a draft", card_path(card), name: "card[status]", value: "drafted", method: :put, class: "btn btn--reversed" %>
</div>
@@ -4,7 +4,7 @@
<% end %>
<div class="position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside" <%= "hidden" if card.closed? %>>
<button class="btn card__hide-on-index tooltip" data-action="click->dialog#open:stop" style="--btn-background: var(--card-bg-color);">
<button class="btn card__hide-on-index" data-action="click->dialog#open:stop" style="--btn-background: var(--card-bg-color);" data-controller="tooltip">
<%= icon_tag "person-add" %>
<span class="for-screen-reader">Assign</span>
</button>
@@ -1,5 +1,5 @@
<%= render "cards/display/common/background", card: card do %>
<%= link_to card.image.presence, class: "btn fill-transparent flex-item-justify-end tooltip", data: { action: "lightbox#open:prevent", lightbox_target: "image" } do %>
<%= link_to card.image.presence, class: "btn fill-transparent flex-item-justify-end", data: { controller: "tooltip", action: "lightbox#open:prevent", lightbox_target: "image" } do %>
<%= icon_tag "picture-zoom" %>
<span class="for-screen-reader">Zoom background image</span>
<% end %>
+1 -1
View File
@@ -1,6 +1,6 @@
<div id="<%= dom_id(card, :tags) %>" class="card__tags">
<div class="position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside" <%= "hidden" if card.closed? %>>
<button class="tag-picker__button btn card__hide-on-index tooltip" data-action="click->dialog#open:stop" style="--btn-background: var(--card-bg-color);">
<button class="tag-picker__button btn card__hide-on-index" data-action="click->dialog#open:stop" style="--btn-background: var(--card-bg-color);" data-controller="tooltip">
<%= icon_tag "tag" %>
<span class="for-screen-reader">Add a tag</span>
</button>
+2 -2
View File
@@ -1,10 +1,10 @@
<div id="<%= dom_id(card, :pin_button) %>">
<% if card.pinned_by? Current.user %>
<%= button_to card_pin_path(card), method: :delete, class: "btn btn--reversed tooltip" do %>
<%= button_to card_pin_path(card), method: :delete, class: "btn btn--reversed", data: { controller: "tooltip" } do %>
<%= icon_tag "pinned" %> <span class="for-screen-reader">Un-pin this card</span>
<% end %>
<% else %>
<%= button_to card_pin_path(card), class: "btn tooltip" do %>
<%= button_to card_pin_path(card), class: "btn", data: { controller: "tooltip" } do %>
<%= icon_tag "unpinned" %> <span class="for-screen-reader">Pin this card</span>
<% end %>
<% end %>
+1 -1
View File
@@ -29,7 +29,7 @@
<%= render "layouts/lightbox" do %>
<% if @card.image.attached? %>
<%= button_to card_image_path(@card), method: :delete, class: "btn tooltip" do %>
<%= button_to card_image_path(@card), method: :delete, class: "btn", data: { controller: "tooltip" } do %>
<%= icon_tag "trash" %>
<span class="for-screen-reader">Remove background image</span>
<% end %>
+2 -2
View File
@@ -1,11 +1,11 @@
<%= turbo_frame_tag dom_id(@card, :watch) do %>
<% if @card.watched_by? Current.user %>
<%= button_to card_watch_path(@card), method: :delete, class: "btn btn--reversed tooltip" do %>
<%= button_to card_watch_path(@card), method: :delete, class: "btn btn--reversed", data: { controller: "tooltip" } do %>
<%= icon_tag "bell" %>
<span class="for-screen-reader">Stop watching</span>
<% end %>
<% else %>
<%= button_to card_watch_path(@card), class: "btn tooltip" do %>
<%= button_to card_watch_path(@card), class: "btn", data: { controller: "tooltip" } do %>
<%= icon_tag "bell-off" %>
<span class="for-screen-reader">Watch this</span>
<% end %>
+1 -1
View File
@@ -8,7 +8,7 @@
<div class="lightbox__actions">
<%= yield %>
<button class="btn fill-white tooltip" data-action="dialog#close keydown.esc->dialog#close:stop" data-controller="hotkey">
<button class="btn fill-white" data-action="dialog#close keydown.esc->dialog#close:stop" data-controller="hotkey tooltip">
<%= icon_tag "remove" %>
<span class="for-screen-reader">Close (esc)</span>
</button>