Merge pull request #2309 from basecamp/mobile/prepare-webviews-2

Mobile/prepare webviews 2
This commit is contained in:
Adrien Maston
2026-01-28 16:03:54 +01:00
committed by GitHub
35 changed files with 232 additions and 92 deletions
+1
View File
@@ -0,0 +1 @@
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M23 0L1.00002 0C0.194222 0 -0.283458 0.955359 0.200023 1.6L9.00002 13.423V22C9.01178 23.585 10.9006 24.5769 12.2 23.6L14.2 22.1C14.696 21.7267 14.9989 21.1208 15 20.5V13.423L23.8 1.6C24.2835 0.955343 23.8058 2.70383e-05 23 0Z" fill="black"/></svg>

After

Width:  |  Height:  |  Size: 317 B

+6
View File
@@ -1,6 +1,12 @@
@layer reset, base, components, modules, utilities, native, platform;
:root {
/* Insets - The mobile apps may inject their own custom insets based on native elements on screen, like a floating navigation */
--custom-safe-inset-top: var(--injected-safe-inset-top, env(safe-area-inset-top, 0px));
--custom-safe-inset-right: var(--injected-safe-inset-right, env(safe-area-inset-right, 0px));
--custom-safe-inset-bottom: var(--injected-safe-inset-bottom, env(safe-area-inset-bottom, 0px));
--custom-safe-inset-left: var(--injected-safe-inset-left, env(safe-area-inset-left, 0px));
/* Spacing */
--inline-space: 1ch;
--inline-space-half: calc(var(--inline-space) / 2);
+7
View File
@@ -3,5 +3,12 @@
.hide-on-android {
display: none;
}
/* Filters
/* ------------------------------------------------------------------------ */
.filters {
--text-x-small: 1rem;
}
}
}
+3 -10
View File
@@ -107,11 +107,6 @@
> * {
grid-area: 1/1;
}
@media (max-width: 639px) {
--btn-size: 3em;
--icon-size: 75%;
}
}
/* Make a normal button circular on mobile */
@@ -125,7 +120,7 @@
inline-size: var(--btn-size);
kbd,
span:last-of-type {
span:last-of-type:not(.icon) {
display: none;
}
}
@@ -224,17 +219,15 @@
.btn--back {
--btn-border-size: 0;
font-size: var(--text-medium);
@media (max-width: 639px) {
padding: 0.5em;
strong, kbd {
display: none;
}
}
@media (min-width: 640px) {
font-size: var(--text-medium);
.icon--arrow-left {
display: none;
}
+1 -1
View File
@@ -232,7 +232,7 @@
overflow-y: auto;
.is-expanded & {
padding: var(--column-padding);
padding: var(--column-padding) var(--column-padding) calc(var(--column-padding) + var(--custom-safe-inset-bottom));
/* Use the rest of the column height for scrolling */
@media (max-width: 639px) {
+10 -6
View File
@@ -220,14 +220,14 @@
.events__column-header {
background-color: var(--color-canvas);
grid-row-start: 1;
inset-block-start: calc(var(--block-space) * -1);
margin-block-end: var(--events-gap);
padding-block: calc(var(--events-gap) * 3) var(--events-gap);
inset-block-start: var(--custom-safe-inset-top);
margin-block: calc(var(--events-gap) * 2) var(--events-gap);
padding-block: var(--events-gap);
position: sticky;
z-index: var(--z-events-column-header);
@media (max-width: 639px) {
margin-inline: calc(var(--main-padding) * -1);
margin-inline: calc(var(--main-padding) * -0.5);
padding-inline: var(--main-padding);
}
}
@@ -239,12 +239,16 @@
}
.events__maximize-button {
inset: calc(var(--events-gap) * 3) 0 auto auto;
inset: 50% var(--events-gap) auto auto;
outline-offset: -2px;
position: absolute;
transform: translateY(-10%);
transform: translateY(-50%);
z-index: 1;
@media (max-width: 639px) {
inset-inline-end: 0;
}
@media (any-hover: hover ) {
opacity: 0;
+13
View File
@@ -0,0 +1,13 @@
@layer components {
.expandable-on-native {
body:not([data-platform~=native]) & {
&::details-content {
display: contents;
}
summary {
display: none;
}
}
}
}
+1 -1
View File
@@ -13,7 +13,7 @@
"menu menu menu"
"actions-start title actions-end";
max-inline-size: 100dvw;
padding-block: calc(var(--block-space-half) + env(safe-area-inset-top)) var(--block-space-half);
padding-block: calc(var(--block-space-half) + var(--custom-safe-inset-top)) var(--block-space-half);
padding-inline: var(--main-padding);
position: relative;
z-index: var(--z-nav);
+20
View File
@@ -1,7 +1,27 @@
@layer platform {
:root:has([data-platform~=ios]) {
&[data-text-size=xsmall] { font-size: 14px; }
&[data-text-size=small] { font-size: 15px; }
&[data-text-size=medium] { font-size: 16px; }
&[data-text-size=large] { font-size: 17px; }
&[data-text-size=xlarge] { font-size: 19px; }
&[data-text-size=xxlarge] { font-size: 21px; }
&[data-text-size=xxxlarge] { font-size: 23px; }
}
[data-platform~=ios] {
.hide-on-ios {
display: none;
}
/* Events
/* ------------------------------------------------------------------------ */
.events__column-header {
-webkit-backdrop-filter: blur(16px);
backdrop-filter: blur(16px);
background-color: oklch(from var(--color-canvas) l c h / 0.5);
border-radius: 10em;
}
}
}
+9 -2
View File
@@ -6,6 +6,13 @@
&.public {
grid-template-rows: auto 1fr auto;
}
&.compact-on-touch {
@media (any-hover: none) {
grid-template-rows: auto 1fr auto;
min-height: unset;
}
}
}
/* Required for the card column page on mobile, but not needed otherwise */
@@ -23,8 +30,8 @@
margin-inline: auto;
max-inline-size: 100dvw;
padding-inline:
calc(var(--main-padding) + env(safe-area-inset-left))
calc(var(--main-padding) + env(safe-area-inset-right));
calc(var(--main-padding) + var(--custom-safe-inset-left))
calc(var(--main-padding) + var(--custom-safe-inset-right));
text-align: center;
}
+17 -3
View File
@@ -3,16 +3,23 @@
--dialog-duration: 350ms;
--lightbox-padding: 3vmin;
align-items: center;
background-color: transparent;
block-size: 100dvh;
border: 0;
display: flex;
inline-size: 100dvw;
inset: 0;
justify-content: center;
margin: auto;
max-height: unset;
max-width: unset;
overflow: hidden;
padding: var(--lightbox-padding);
padding:
calc(var(--lightbox-padding) + var(--custom-safe-inset-top))
calc(var(--lightbox-padding) + var(--custom-safe-inset-right))
calc(var(--lightbox-padding) + var(--custom-safe-inset-bottom))
calc(var(--lightbox-padding) + var(--custom-safe-inset-left));
text-align: center;
&::backdrop {
@@ -47,12 +54,15 @@
.lightbox__actions {
display: flex;
gap: 1ch;
inset: var(--lightbox-padding) var(--lightbox-padding) auto auto;
inset:
calc(var(--lightbox-padding) + var(--custom-safe-inset-top))
calc(var(--lightbox-padding) + var(--custom-safe-inset-right))
auto
auto;
position: absolute;
}
.lightbox__figure {
align-self: stretch;
animation-fill-mode: forwards;
animation: slide-down var(--dialog-duration);
display: flex;
@@ -72,6 +82,10 @@
&:empty {
display: none;
}
&[tabindex="-1"]:focus-visible {
outline: unset;
}
}
.lightbox__image {
+20 -7
View File
@@ -1,11 +1,5 @@
@layer native {
[data-platform~=native] {
/* The mobile apps may inject their own custom insets based on native elements on screen, like a floating navigation */
--custom-safe-inset-top: var(--injected-safe-inset-top, env(safe-area-inset-top, 0px));
--custom-safe-inset-right: var(--injected-safe-inset-right, env(safe-area-inset-right, 0px));
--custom-safe-inset-bottom: var(--injected-safe-inset-bottom, env(safe-area-inset-bottom, 0px));
--custom-safe-inset-left: var(--injected-safe-inset-left, env(safe-area-inset-left, 0px));
--footer-height: 0;
-webkit-tap-highlight-color: transparent;
@@ -14,6 +8,15 @@
display: none;
}
/* Layout
/* ------------------------------------------------------------------------ */
&:not(.contained-scrolling) {
#main {
padding-block-end: var(--custom-safe-inset-bottom);
}
}
/* Header
/* ------------------------------------------------------------------------ */
@@ -21,7 +24,12 @@
:not(:has(.header__title, .header__actions)),
:not(:has(.header__title, .header__actions--end)):has(.header__actions--start .btn--back:only-child)
) {
display: none;
block-size: var(--custom-safe-inset-top);
padding: unset;
* {
display: none;
}
}
.header__actions {
@@ -48,6 +56,11 @@
}
}
.card-perma__bg {
border-start-start-radius: calc(0.2em + clamp(0.25rem, 2vw, var(--padding-block)));
border-start-end-radius: calc(0.2em + clamp(0.25rem, 2vw, var(--padding-block)));
}
.card-perma__closure-message {
margin-block: var(--block-space);
translate: unset;
+2 -2
View File
@@ -27,13 +27,13 @@
&:where(.popup--align-left),
&.orient-left {
inset-inline: auto 0;
transform: translateX(0);
transform: translateX(var(--orient-offset, 0px));
}
&:where(.popup--align-right),
&.orient-right {
inset-inline: 0 auto;
transform: translateX(0);
transform: translateX(var(--orient-offset, 0px));
}
form {
+3 -1
View File
@@ -29,7 +29,9 @@
}
.settings__panel--users {
max-height: 80dvh;
@media (min-width: 640px) {
max-height: 80dvh;
}
@media (min-width: 960px) {
max-height: calc(100dvh - 12rem);
+2 -2
View File
@@ -20,12 +20,12 @@
&.orient-right {
inset-inline: 0 auto;
translate: 0 -100%;
translate: var(--orient-offset, 0px) -100%;
}
&.orient-left {
inset-inline: auto 0;
translate: 0 -100%;
translate: var(--orient-offset, 0px) -100%;
}
}
+1 -1
View File
@@ -11,7 +11,7 @@ module ApplicationHelper
end
def back_link_to(label, url, action, **options)
link_to url, class: "btn btn--back", data: { controller: "hotkey", action: action }, **options do
link_to url, class: "btn btn--back btn--circle-mobile", data: { controller: "hotkey", action: action }, **options do
icon_tag("arrow-left") + tag.strong("Back to #{label}", class: "overflow-ellipsis") + tag.kbd("ESC", class: "txt-x-small hide-on-touch").html_safe
end
end
+1 -1
View File
@@ -4,7 +4,7 @@ module BoardsHelper
end
def link_to_edit_board(board)
link_to edit_board_path(board), class: "btn",
link_to edit_board_path(board), class: "btn btn--circle-mobile",
data: { controller: "tooltip", bridge__overflow_menu_target: "item", bridge_title: "Board settings" } do
icon_tag("settings") + tag.span("Settings for #{board.name}", class: "for-screen-reader")
end
+1 -1
View File
@@ -24,7 +24,7 @@ module WebhooksHelper
def link_to_webhooks(board, &)
link_to board_webhooks_path(board_id: board),
class: [ "btn", { "btn--reversed": board.webhooks.any? } ],
class: [ "btn btn--circle-mobile", { "btn--reversed": board.webhooks.any? } ],
data: { controller: "tooltip", bridge__overflow_menu_target: "item", bridge_title: "Webhooks" } do
icon_tag("world") + tag.span("Webhooks", class: "for-screen-reader")
end
@@ -26,7 +26,7 @@ export default class extends Controller {
this.dialogTarget.showModal()
} else {
this.dialogTarget.show()
orient(this.dialogTarget)
orient({ target: this.dialogTarget, anchor: this.element })
}
this.loadLazyFrames()
@@ -46,7 +46,7 @@ export default class extends Controller {
this.dialogTarget.close()
this.dialogTarget.setAttribute("aria-hidden", "true")
this.dialogTarget.blur()
orient(this.dialogTarget, false)
orient({ target: this.dialogTarget, reset: true })
this.dispatch("close")
}
@@ -0,0 +1,16 @@
import { Controller } from "@hotwired/stimulus"
import { isNative } from "helpers/platform_helpers"
export default class extends Controller {
static get shouldLoad() {
return isNative()
}
static values = { autoExpandSelector: String }
connect() {
if (this.hasAutoExpandSelectorValue && this.element.querySelector(this.autoExpandSelectorValue)) {
this.element.open = true
}
}
}
@@ -30,7 +30,7 @@ export default class extends Controller {
reset() {
this.zoomedImageTarget.src = ""
this.captionTarget.innerText = ""
this.captionTarget.innerHtml = "&nbsp;"
this.dispatch('closed')
}
@@ -15,11 +15,11 @@ export default class extends Controller {
}
mouseEnter(event) {
orient(this.#tooltipElement)
orient({ target: this.#tooltipElement, anchor: this.element })
}
mouseOut(event) {
orient(this.#tooltipElement, false)
orient({ target: this.#tooltipElement, reset: true })
}
get #tooltipElement() {
@@ -0,0 +1,16 @@
import { Controller } from "@hotwired/stimulus"
import { isTouchDevice } from "helpers/platform_helpers"
export default class extends Controller {
static get shouldLoad() {
return isTouchDevice()
}
static values = { placeholder: String }
connect() {
if (this.hasPlaceholderValue) {
this.element.placeholder = this.placeholderValue
}
}
}
+29 -13
View File
@@ -1,24 +1,40 @@
const EDGE_THRESHOLD = 16
export function orient(el, orient = true) {
el.classList.remove("orient-left", "orient-right")
export function orient({ target, anchor = null, reset = false }) {
target.classList.remove("orient-left", "orient-right")
target.style.removeProperty("--orient-offset")
if (!orient) return
if (reset) return
const rightSpace = spaceOnRight(el)
const leftSpace = spaceOnLeft(el)
const targetGeometry = geometry(target)
const anchorGeometry = geometry(anchor)
const shouldOrientLeft = targetGeometry.spaceOnRight < EDGE_THRESHOLD && targetGeometry.spaceOnRight < targetGeometry.spaceOnLeft
const shouldOrientRight = targetGeometry.spaceOnLeft < EDGE_THRESHOLD && targetGeometry.spaceOnLeft < targetGeometry.spaceOnRight
if (rightSpace < EDGE_THRESHOLD && rightSpace < leftSpace) {
el.classList.add("orient-left")
} else if (leftSpace < EDGE_THRESHOLD && leftSpace < rightSpace) {
el.classList.add("orient-right")
if (shouldOrientLeft) {
orientLeft({ el: target, targetGeometry, anchorGeometry })
} else if (shouldOrientRight) {
orientRight({ el: target, targetGeometry, anchorGeometry })
}
}
function spaceOnLeft(el) {
return el.getBoundingClientRect().left
function orientLeft({ el, targetGeometry, anchorGeometry }) {
const offset = Math.min(0, anchorGeometry.spaceOnLeft + anchorGeometry.width - targetGeometry.width) * -1
el.classList.add("orient-left")
el.style.setProperty("--orient-offset", `${offset}px`)
}
function spaceOnRight(el) {
return window.innerWidth - el.getBoundingClientRect().right
function orientRight({ el, targetGeometry, anchorGeometry }) {
const offset = Math.max(0, anchorGeometry.spaceOnLeft + targetGeometry.width - window.innerWidth) * -1
el.classList.add("orient-right")
el.style.setProperty("--orient-offset", `${offset}px`)
}
function geometry(el) {
const rect = el.getBoundingClientRect()
return {
spaceOnLeft: rect.left,
spaceOnRight: window.innerWidth - rect.right,
width: rect.width
}
}
@@ -13,3 +13,7 @@ export function isAndroid() {
export function isMobile() {
return isIos() || isAndroid()
}
export function isNative() {
return /Hotwire Native/.test(navigator.userAgent)
}
+1
View File
@@ -1,4 +1,5 @@
<% @page_title = "Create a new board" %>
<% @body_class = "compact-on-touch" %>
<div class="panel panel--centered">
<%= bridged_form_with model: @board, class: "flex flex-column gap", data: { controller: "form", action: "submit->form#preventEmptySubmit" } do |form| %>
+1 -1
View File
@@ -1,5 +1,5 @@
<div class="cards__new-column" data-controller="dialog" data-action="keydown.esc->dialog#close click@document->dialog#closeOnClickOutside" data-turbo-permanent>
<button class="btn btn--circle txt-x-small borderless" data-controller="tooltip" data-action="click->dialog#open:stop">
<button class="btn btn--circle btn--circle-mobile txt-x-small borderless" data-controller="tooltip" data-action="click->dialog#open:stop">
<%= icon_tag "add", class: "translucent" %>
<span class="for-screen-reader">Add a column</span>
</button>
+2 -2
View File
@@ -1,11 +1,11 @@
<% if card.golden? %>
<%= button_to card_goldness_path(card), method: :delete, class: "btn btn--reversed",
<%= button_to card_goldness_path(card), method: :delete, class: "btn btn--reversed btn--circle-mobile",
data: { controller: "tooltip hotkey", action: "keydown.shift+g@document->hotkey#click", bridge__overflow_menu_target: "item", bridge_title: "Demote to normal" } do %>
<%= icon_tag "golden-ticket" %>
<span class="for-screen-reader">Demote to normal (shift+g)</span>
<% end %>
<% else %>
<%= button_to card_goldness_path(card), class: "btn",
<%= button_to card_goldness_path(card), class: "btn btn--circle-mobile",
data: { controller: "tooltip hotkey", action: "keydown.shift+g@document->hotkey#click", bridge__overflow_menu_target: "item", bridge_title: "Promote to Golden Ticket" } do %>
<%= icon_tag "golden-ticket" %>
<span class="for-screen-reader">Promote to Golden Ticket (shift+g)</span>
+1 -1
View File
@@ -6,7 +6,7 @@
<% end %>
<% elsif !card.closed? %>
<%= form_with model: card, data: { controller: "form" } do |form| %>
<label class="card-perma__image-btn btn input--file" data-controller="tooltip" data-bridge--overflow-menu-target="item" data-bridge-title="Add background image">
<label class="card-perma__image-btn btn input--file btn--circle-mobile" data-controller="tooltip" data-bridge--overflow-menu-target="item" data-bridge-title="Add background image">
<%= icon_tag "picture-add" %>
<span class="for-screen-reader">Add background image</span>
+2 -2
View File
@@ -1,11 +1,11 @@
<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",
<%= button_to card_pin_path(card), method: :delete, class: "btn btn--reversed btn--circle-mobile",
data: { controller: "tooltip hotkey", action: "keydown.shift+p@document->hotkey#click", bridge__overflow_menu_target: "item", bridge_title: "Un-pin this card" } do %>
<%= icon_tag "pinned" %> <span class="for-screen-reader">Un-pin this card (shift+p)</span>
<% end %>
<% else %>
<%= button_to card_pin_path(card), class: "btn",
<%= button_to card_pin_path(card), class: "btn btn--circle-mobile",
data: { controller: "tooltip hotkey", action: "keydown.shift+p@document->hotkey#click", bridge__overflow_menu_target: "item", bridge_title: "Pin this card" } do %>
<%= icon_tag "unpinned" %> <span class="for-screen-reader">Pin this card (shift+p)</span>
<% end %>
@@ -1,12 +1,12 @@
<div id="<%= dom_id(card, :watch_button) %>">
<% if card.watched_by? Current.user %>
<%= button_to card_watch_path(card), method: :delete, class: "btn btn--reversed",
<%= button_to card_watch_path(card), method: :delete, class: "btn btn--reversed btn--circle-mobile",
data: { controller: "tooltip hotkey", action: "keydown.shift+n@document->hotkey#click", bridge__overflow_menu_target: "item", bridge_title: "Stop watching" } do %>
<%= icon_tag "bell" %>
<span class="for-screen-reader">Stop watching (shift+n)</span>
<% end %>
<% else %>
<%= button_to card_watch_path(card), class: "btn",
<%= button_to card_watch_path(card), class: "btn btn--circle-mobile",
data: { controller: "tooltip hotkey", action: "keydown.shift+n@document->hotkey#click", bridge__overflow_menu_target: "item", bridge_title: "Watch this" } do %>
<%= icon_tag "bell-off" %>
<span class="for-screen-reader">Watch this (shift+n)</span>
+30 -24
View File
@@ -1,29 +1,35 @@
<%= tag.aside \
class: class_names("filters margin-block-end", { "filters--expanded": user_filtering.expanded? }),
<%= tag.details class: "expandable-on-native",
data: {
controller: "toggle-enable toggle-class filter-settings dialog-manager",
toggle_class_toggle_class: "filters--expanded",
filter_settings_filters_set_class: "filters--has-filters-set",
filter_settings_no_filtering_url_value: no_filtering_url,
filter_settings_refresh_url_value: settings_refresh_path,
filter_settings_cards_url_value: cards_path,
turbo_permanent: true } do %>
<%= form_with url: filter_url, method: :get, class: "display-contents", data: {
controller: "form",
turbo_frame: "cards_container",
filter_settings_target: "form",
action: "turbo:submit-end->filter-settings#resetIfNoFiltering",
turbo_action: "advance" } do |form| %>
<%= hidden_field_tag :expand_all, true, disabled: !user_filtering.expanded?, data: { toggle_enable_target: "element" } %>
controller: "expandable-on-native",
expandable_on_native_auto_expand_selector_value: "[data-filter-show=true]" } do %>
<%= tag.summary "Toggle filters", class: "btn btn--plain margin-block-end", data: { bridge__buttons_target: "button", bridge_title: "Toggle filters", bridge_icon_url: bridge_icon("funnel") } %>
<%= tag.aside \
class: class_names("filters margin-block-end", { "filters--expanded": user_filtering.expanded? }),
data: {
controller: "toggle-enable toggle-class filter-settings dialog-manager",
toggle_class_toggle_class: "filters--expanded",
filter_settings_filters_set_class: "filters--has-filters-set",
filter_settings_no_filtering_url_value: no_filtering_url,
filter_settings_refresh_url_value: settings_refresh_path,
filter_settings_cards_url_value: cards_path,
turbo_permanent: true } do %>
<%= form_with url: filter_url, method: :get, class: "display-contents", data: {
controller: "form",
turbo_frame: "cards_container",
filter_settings_target: "form",
action: "turbo:submit-end->filter-settings#resetIfNoFiltering",
turbo_action: "advance" } do |form| %>
<%= hidden_field_tag :expand_all, true, disabled: !user_filtering.expanded?, data: { toggle_enable_target: "element" } %>
<%= yield form if block_given? %>
<%= render "filters/settings/terms", filter: user_filtering.filter, form: form do %>
<%= yield form if block_given? %>
<% end %>
<%= render "filters/settings/controls", user_filtering: user_filtering, form: form %>
<%= render "filters/settings/toggle", user_filtering: user_filtering %>
<% end %>
<%= render "filters/settings/manage", user_filtering: user_filtering, no_filtering_url: no_filtering_url %>
<%= render "filters/settings/terms", filter: user_filtering.filter, form: form do %>
<%= yield form if block_given? %>
<% end %>
<%= render "filters/settings/controls", user_filtering: user_filtering, form: form %>
<%= render "filters/settings/toggle", user_filtering: user_filtering %>
<% end %>
<%= render "filters/settings/manage", user_filtering: user_filtering, no_filtering_url: no_filtering_url %>
<% end %>
<% end %>
+2 -1
View File
@@ -1,8 +1,9 @@
<%= form.search_field "terms[]", placeholder: "Filter these cards… [F]", class: "filter__terms input txt-x-small",
autofocus: false, autocomplete: :off, autocorrect: "off", data: {
"1p-ignore": "true",
controller: "hotkey",
controller: "hotkey touch-placeholder",
filter_settings_target: "field",
touch_placeholder_placeholder_value: "Filter these cards…",
action: "keydown.f@document->hotkey#focus input->filter-settings#resetIfNoFiltering input->form#debouncedSubmit keydown.enter->form#submitToTopTarget blur->form#submitToTopTarget" } %>
<% if filter.terms.present? %>
+2 -2
View File
@@ -3,12 +3,12 @@
<figure class="lightbox__figure">
<img src="" class="lightbox__image" data-lightbox-target="zoomedImage" />
<figcaption class="lightbox__caption" data-lightbox-target="caption"></figcaption>
<figcaption class="lightbox__caption" data-lightbox-target="caption" tabindex="-1" data-dialog-target="focusTouch">&nbsp</figcaption>
</figure>
<div class="lightbox__actions">
<%= yield %>
<button class="btn fill-white" data-action="dialog#close" data-controller="hotkey tooltip">
<button class="btn fill-white" data-action="dialog#close" data-controller="hotkey tooltip" data-dialog-target="focusMouse">
<%= icon_tag "remove" %>
<span class="for-screen-reader">Close (esc)</span>
</button>
+1 -1
View File
@@ -9,7 +9,7 @@
<h1 class="header__title" data-bridge--title-target="header"><%= @page_title %></h1>
<div class="header__actions header__actions--end">
<%= link_to notifications_settings_path, class: "btn", data: { bridge__overflow_menu_target: "item", bridge_title: "Notification settings" } do %>
<%= link_to notifications_settings_path, class: "btn btn--circle-mobile", data: { bridge__overflow_menu_target: "item", bridge_title: "Notification settings" } do %>
<%= icon_tag "settings" %> <span class="for-screen-reader">Notification settings</span>
<% end %>
</div>