Merge pull request #2309 from basecamp/mobile/prepare-webviews-2
Mobile/prepare webviews 2
This commit is contained in:
@@ -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 |
@@ -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);
|
||||
|
||||
@@ -3,5 +3,12 @@
|
||||
.hide-on-android {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Filters
|
||||
/* ------------------------------------------------------------------------ */
|
||||
|
||||
.filters {
|
||||
--text-x-small: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
@layer components {
|
||||
.expandable-on-native {
|
||||
body:not([data-platform~=native]) & {
|
||||
&::details-content {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
summary {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = " "
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,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,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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 %>
|
||||
|
||||
@@ -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? %>
|
||||
|
||||
@@ -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"> </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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user