Merge pull request #302 from basecamp/a11y-first-round
First round of accessibility fixes
This commit is contained in:
@@ -263,6 +263,7 @@
|
||||
}
|
||||
|
||||
/* Accessibility */
|
||||
.visually-hidden,
|
||||
.for-screen-reader {
|
||||
block-size: 1px;
|
||||
clip-path: inset(50%);
|
||||
|
||||
@@ -10,8 +10,10 @@ module AvatarsHelper
|
||||
AVATAR_COLORS[Zlib.crc32(user.to_param) % AVATAR_COLORS.size]
|
||||
end
|
||||
|
||||
def avatar_tag(user, **options)
|
||||
link_to user_path(user), title: user.name, class: "btn avatar", data: { turbo_frame: "_top" } do
|
||||
def avatar_tag(user, hidden_for_screen_reader: false, **options)
|
||||
link_to user_path(user), title: user.name, class: "btn avatar", data: { turbo_frame: "_top" },
|
||||
aria: { hidden: hidden_for_screen_reader, label: user.name },
|
||||
tabindex: hidden_for_screen_reader ? -1 : nil do
|
||||
avatar_image_tag(user, **options)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@ module MessagesHelper
|
||||
turbo_frame_tag dom_id(bubble, :messages),
|
||||
class: "comments align-center center borderless margin flex flex-column gap-half",
|
||||
style: "--bubble-color: <%= bubble.color %>",
|
||||
role: "group", aria: { label: "Messages" },
|
||||
data: {
|
||||
controller: "created-by-current-user",
|
||||
created_by_current_user_mine_class: "comment--mine"
|
||||
|
||||
@@ -6,14 +6,15 @@ export default class extends Controller {
|
||||
static values = { reacterId: Number }
|
||||
|
||||
connect() {
|
||||
if (this.#currentUserIsreacter) {
|
||||
if (this.#currentUserIsReacter) {
|
||||
this.#setAccessibleAttributes()
|
||||
}
|
||||
}
|
||||
|
||||
reveal() {
|
||||
if (this.#currentUserIsreacter) {
|
||||
if (this.#currentUserIsReacter) {
|
||||
this.element.classList.toggle(this.revealClass)
|
||||
this.contentTarget.ariaExpanded = this.element.classList.contains(this.revealClass)
|
||||
this.buttonTarget.focus()
|
||||
}
|
||||
}
|
||||
@@ -23,11 +24,12 @@ export default class extends Controller {
|
||||
}
|
||||
|
||||
#setAccessibleAttributes() {
|
||||
this.contentTarget.setAttribute('tabindex', '0')
|
||||
this.contentTarget.setAttribute('aria-describedby', 'delete_reaction_accessible_label')
|
||||
this.contentTarget.role = "button"
|
||||
this.contentTarget.tabIndex = 0
|
||||
this.contentTarget.ariaExpanded = false
|
||||
}
|
||||
|
||||
get #currentUserIsreacter() {
|
||||
get #currentUserIsReacter() {
|
||||
return Current.user.id === this.reacterIdValue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<%= tag.div class: "bubble__detail bubble__boosts",
|
||||
role: "group", aria: { label: "Boosts" },
|
||||
data: {
|
||||
controller: "animation toggle-class",
|
||||
animation_play_class: "boosting",
|
||||
@@ -8,7 +9,7 @@
|
||||
<%= form_with url: bucket_bubble_boosts_path(bubble.bucket, bubble),
|
||||
class: "boost__form",
|
||||
data: { action: "toggle-class#toggle" } do %>
|
||||
<%= text_field_tag :boost_count, bubble.boosts_count, min: 1, class: "input borderless boost__input", autocomplete: "off" %>
|
||||
<%= tag.button "+", class: "btn btn--plain boost__btn", type: :submit %>
|
||||
<%= text_field_tag :boost_count, bubble.boosts_count, min: 1, class: "input borderless boost__input", autocomplete: "off", aria: { label: "Boost count" } %>
|
||||
<%= tag.button "+", class: "btn btn--plain boost__btn", type: :submit, aria: { label: "Boost" } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<% bubble.assignees.each do |assignee| %>
|
||||
<article class="bubble__detail bubble__assignee">
|
||||
<div class="btn btn--plain position-relative fill-transparent">
|
||||
<span class="assignee__name"><span><%= assignee.name %></span></span>
|
||||
<%= avatar_image_tag assignee, loading: :lazy, class: "avatar flex-item-no-shrink" %>
|
||||
<span class="assignee__name" aria-hidden="true"><span><%= assignee.name %></span></span>
|
||||
<%= avatar_image_tag assignee, loading: :lazy, class: "avatar flex-item-no-shrink", aria: { hidden: true } %>
|
||||
<span class="for-screen-reader">Assigned to <%= assignee.name %></span>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
<% cache bubble do %>
|
||||
<div class="<%= class_names("bubble", drafted: bubble.drafted?, popped: bubble.popped?) %>"
|
||||
style="view-transition-name: bubble-<%= bubble.id -%>; --bubble-color: <%= bubble.color %>; <%= bubble_rotation(bubble) %>"
|
||||
data-bubble-size-target="bubble"
|
||||
data-activity-score="<%= bubble.activity_score %>"
|
||||
data-activity-score-at="<%= bubble.activity_score_at.to_i %>"
|
||||
data-controller="animation upload-preview"
|
||||
data-animation-play-class="bubble--wobble"
|
||||
data-animation-play-on-load-value="true"
|
||||
data-action="mouseover->animation#play">
|
||||
|
||||
<%= tag.div class: [ "bubble", drafted: bubble.drafted?, popped: bubble.popped? ],
|
||||
style: "view-transition-name: bubble-#{bubble.id}; --bubble-color: #{bubble.color}; #{bubble_rotation(bubble)}",
|
||||
role: "group", aria: { label: bubble.title },
|
||||
data: {
|
||||
bubble_size_target: "bubble",
|
||||
activity_score: bubble.activity_score,
|
||||
activity_score_at: bubble.activity_score_at.to_i,
|
||||
controller: "animation upload-preview",
|
||||
animation_play_class: "bubble--wobble",
|
||||
animation_play_on_load_value: true,
|
||||
action: "mouseover->animation#play" } do %>
|
||||
<div>
|
||||
<h1 class="bubble__title">
|
||||
<h1 class="bubble__title" role="presentation">
|
||||
<% if bubble.published? %>
|
||||
<%= turbo_frame_tag bubble, :edit do %>
|
||||
<%= link_to bubble_title(bubble), edit_bucket_bubble_path(bubble.bucket, bubble), class: "txt-undecorated bubble__title-rendered" %>
|
||||
<%= link_to bubble_title(bubble), edit_bucket_bubble_path(bubble.bucket, bubble),
|
||||
class: "txt-undecorated bubble__title-rendered",
|
||||
role: "button", aria: { label: "Edit name: #{bubble.title}" } %>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), id: "bubble_form", data: { controller: "auto-save" } do |form| %>
|
||||
@@ -30,14 +33,16 @@
|
||||
<div class="bubble__shape"></div>
|
||||
<svg class="bubble__splat" viewBox="0 0 934 914" xmlns="http://www.w3.org/2000/svg"><circle cx="485.2" cy="467.2" r="286.5"/><path d="m197.7 219.1c-.2-7.1 5.8-11.7 12.7-13.2 34-7.1 53.5 29.2 81.4 40 39.5 6.4 25.9-54 30.8-77.7 17.2-65.3 78.4 67.2 108.2 55.7 26.8-17.3 25.9-58.8 38.7-86.1 9.6-41.5 30.4-2.6 48.6 10.1 14.2 11.2 31.9 17.9 45.1 29.9 13 11.2 20 29.1 35.8 36.8 20.2 9.1 44.8 2.3 65.2 11.8 18.3 7.2 33.8 22.6 52.5 30.4 23 8.6 42.4 1.8 37.8 35.1 2.7 36.8 38.3 71.9 40.1 108.6-.2 21.1-30.1 21.7-22.4 36.3 22.1 32.5-7.7 51.1 21 93.3 7 43.2-91.2-7.2-14.3 78.2 13.2 13.7 22.3 28.2 4.5 40.2-18.7 18.4-19.5 18.4-45 13.8-15.5-1.2 1.8 16.5-4.6 22.7-21.1 8-6.7 22-14.6 34.9-6 3.2-14.7-2.6-21.1-4-17.2-6.2-11.5 17.5-15.3 25.7-4 7.3-15.6 1.5-22.2-.2-26.7-10.8-55.1-3.1-82.4-.2-14.2 1.1-26 2.2-30.2 18.3-8 20.8-7.5 87.5-41.5 68.5-15.3-7.2-29.8-51.7-45.3-26.4-2.8 3.9-6.4 9.3-11.2 5.9-20.7-27.6-17-71-54.3-25.6-29.6 29.4-32.5 2.5-48.8-20.5-18.9-17.1-48.4-20.5-61.6-44.6-18.5-27.6-35.8-54.6-60.2-77.9-10.5-10.8-60.9-17.2-34.7-35.6 42.5-23.5-50.6-14-19.6-30.8 33.5-11.7 12.7-23.2-10.3-28.1-6.2-1.9-22-3.3-22.7-8.2 2.9-11.2 13.8-26.5 22.6-35.7 38.3-20.1-7-33.5-23.6-48.2-4-4.4 4.8-2.9 5.5-5.8-7.4-11.8-11.8-10-.4-21.8 3.2-7.8-4.9-17.6-3.8-25.5 8.1-21 57.9-6.5 64.2-36.2-3.5-26.1-16.4-50.3 3.5-75 5.9-8.8 22.4-16.8 19.3-28.7-5.7-14.7-26.4-23.7-27.6-40.2z"/><path d="m573 256.7s29.6-24.9 55-64.4 40.3-158 88.1-127.9c44.4 28-27.7 97.3-60.3 143.3-32.6 45.9-14.3 85.7-14.3 85.7l-68.5-36.6z"/><path d="m606.4 674.7s-11.3 37-11.2 84c0 47 51.9 154.6-4.6 155.3-52.5.6-29.6-96.8-27.1-153.1s-34.5-79.7-34.5-79.7z"/><path d="m325.5 622.7s-34 16.1-71.9 44c-37.8 27.9-104.9 118.2-126.8 89.7-20.3-26.5 66.8-72.5 113.1-104.6s51.2-64.9 51.2-64.9l34.4 35.9z"/><path d="m225.7 388.5s-30.8-35.1-75.8-72.7c-45.1-37.5-169.2-98.3-146.9-126.5 20.8-26.1 104.8 63 157.6 109.3 52.9 46.2 90.4 46.9 90.4 46.9l-25.4 43z"/><path d="m327.7 593.7s-47.6 1.4-103.9 17.7c-56.3 16.2-170.6 104.9-187.6 48.8-15.8-52.2 107.7-62.8 175.9-79.7s85.8-61.9 85.8-61.9l29.9 75.1z"/><path d="m443.5 344.2s0-46.7-8.9-104.6c-9-57.9-62-185.6-26.7-192 32.9-5.9 37 116.5 46.2 186.2 9.2 69.6 36.9 95 36.9 95l-47.5 15.5z"/><path d="m433.2 340.9s-6.8-37-19.5-82.8c-12.8-45.8-56.9-146.5-40.8-151.7 15-4.8 34.8 92 49.3 147s31.6 74.9 31.6 74.9l-20.6 12.5z"/><path d="m496.8 298.1s10.8-45.7 13.6-104.2c2.8-58.6-29.9-194.6 12.9-193.4 39.8 1.1 16.5 121.7 11.2 191.8-5.3 70 21.3 100.6 21.3 100.6l-59.1 5.2z"/><path d="m647.8 525s22.1 41.1 57.6 87.8c35.4 46.7 142.8 133.8 114.7 156.2-26.1 20.8-88-84.9-129.1-141.8-41.2-56.9-77.6-66-77.6-66z"/><path d="m658.4 523s23.5 29.3 56.5 63.5 119.7 101.9 108 114.1c-10.9 11.4-74.3-64.4-113.3-105.9s-63.4-50.9-63.4-50.9z"/><path d="m622.8 591s12.2 45.3 37.6 98.2 118.8 157 80.6 176.3c-35.6 17.9-72.4-99.3-101.1-163.4-28.6-64.1-66.6-78.4-66.6-78.4l49.5-32.6z"/><path d="m613.7 441.6s43.3 17.5 100.4 30.7c57.1 13.3 195.4 11.6 188.1 46.8-6.8 32.7-121.9-9.1-189.9-26.6s-101.9-1.2-101.9-1.2l3.3-49.8z"/><path d="m666.2 496.5s38.4 27.1 91.7 51.5 191.7 44.8 174.6 84.1c-15.9 36.5-119.1-30.1-182.2-61.1-63-31-101.3-17.7-101.3-17.7l17.2-56.7z"/><path d="m57.2 500.1c-7.1-1.3-14.4-2-21.5-.7-13.9 2.4-27.3 11.4-31.7 25.2-5 15.2 2.5 30.2 12.9 41.7 7.5 8.5 16.3 16.5 27.6 16.6 19.9-.7 36.3-19.9 37.6-39 1.6-18.3-8.2-36.2-27.2-40.2-3.5-.8-7.2-1.2-10.8-1.5"/><path d="m796.1 362.9c5.4 21.4 22.7 41 44.2 46.3 16.7 4.5 33.7-3 43.2-17.2 24.3-38.2-3-125.5-53.2-116.5-8 1.5-15.8 5.8-21.4 11.6-18.2 19.3-19.3 51.3-12.8 75.6z"/><path d="m255.1 782.9c5.4 21.4 22.7 41 44.2 46.3 16.7 4.5 33.7-3 43.2-17.2 24.3-38.2-3-125.5-53.2-116.5-8 1.5-15.8 5.8-21.4 11.6-18.2 19.3-19.3 51.3-12.8 75.6z"/><path d="m771 224.4c-3.4-.5-6.8-1-10.2-1.1-23.8-1.1-36.1 23.5-16.7 36.4 9.4 6.3 22.2 2.4 26.7-7.7 5.2-11.6-.7-20.3-10.6-26.9"/><path d="m402 812.4c-3.4-.5-6.8-1-10.2-1.1-23.8-1.1-36.1 23.5-16.7 36.4 9.4 6.3 22.2 2.4 26.7-7.7 5.2-11.6-.7-20.3-10.6-26.9"/></svg>
|
||||
|
||||
<%= link_to bucket_bubble_path(bubble.bucket, bubble), class: "bubble__link" do %>
|
||||
<span class="for-screen-reader"><%= bubble.title %></span>
|
||||
<% end %>
|
||||
<h2 contents>
|
||||
<%= link_to bucket_bubble_path(bubble.bucket, bubble), class: "bubble__link" do %>
|
||||
<span class="for-screen-reader"><%= bubble.title %></span>
|
||||
<% end %>
|
||||
</h2>
|
||||
|
||||
<%= render "bubbles/assignments", bubble: bubble %>
|
||||
<%= render "bubbles/boosts", bubble: bubble %>
|
||||
<%= render "bubbles/comments", bubble: bubble %>
|
||||
<%= render "bubbles/date", bubble: bubble %>
|
||||
<%= render "bubbles/image", bubble: bubble %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<% if bubble.messages.comments.any? %>
|
||||
<div class="bubble__detail bubble__comments">
|
||||
<span><%= bubble.messages.comments.count %></span>
|
||||
<span aria-hidden="true"><%= bubble.messages.comments.count %></span>
|
||||
<span class="for-screen-reader"><%= pluralize(bubble.messages.comments.count, "comment") %></span>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<% if bubble.due_on.present? %>
|
||||
<%= form_with model: bubble, url: bucket_bubble_path(bubble.bucket, bubble), data: { controller: "form" } do |form| %>
|
||||
<label class="bubble__detail bubble__date">
|
||||
<span class="for-screen-reader">Change the due date</span>
|
||||
<span class="bubble__date-text"><%= html_escape bubble.due_on.strftime("%b <br> %d").html_safe %></span>
|
||||
<%= form.date_field :due_on, class: "input input--hidden", data: { action: "change->form#submit click->form#showPicker" } %>
|
||||
<span class="for-screen-reader">Change the due date</span>
|
||||
</label>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="bubble__image">
|
||||
<%= image_tag bubble.image.presence || "", data: { upload_preview_target: "image" } %>
|
||||
<%= image_tag bubble.image.presence || "", data: { upload_preview_target: "image" }, aria: { hidden: true } %>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<li class="<%= class_names("flex align-center gap-half margin-none", drafted: bubble.drafted?, popped: bubble.popped?) %>" style="--bubble-color: <%= bubble.color %>; <%= bubble_rotation(bubble) %>"
|
||||
data-controller="animation" data-animation-play-class="bubble--wobble" data-animation-play-on-load-value="true" data-action="mouseover->animation#play">
|
||||
<%= link_to bucket_bubble_path(bubble.bucket, bubble), class: "flex-item-no-shrink" do %>
|
||||
<%= link_to bucket_bubble_path(bubble.bucket, bubble), class: "flex-item-no-shrink",
|
||||
aria: { hidden: true }, tabindex: -1 do %>
|
||||
<div class="bubble__shape flex-item-no-shrink"></div>
|
||||
<svg class="bubble__splat flex-item-no-shrink" viewBox="0 0 934 914" xmlns="http://www.w3.org/2000/svg"><circle cx="485.2" cy="467.2" r="286.5"/><path d="m197.7 219.1c-.2-7.1 5.8-11.7 12.7-13.2 34-7.1 53.5 29.2 81.4 40 39.5 6.4 25.9-54 30.8-77.7 17.2-65.3 78.4 67.2 108.2 55.7 26.8-17.3 25.9-58.8 38.7-86.1 9.6-41.5 30.4-2.6 48.6 10.1 14.2 11.2 31.9 17.9 45.1 29.9 13 11.2 20 29.1 35.8 36.8 20.2 9.1 44.8 2.3 65.2 11.8 18.3 7.2 33.8 22.6 52.5 30.4 23 8.6 42.4 1.8 37.8 35.1 2.7 36.8 38.3 71.9 40.1 108.6-.2 21.1-30.1 21.7-22.4 36.3 22.1 32.5-7.7 51.1 21 93.3 7 43.2-91.2-7.2-14.3 78.2 13.2 13.7 22.3 28.2 4.5 40.2-18.7 18.4-19.5 18.4-45 13.8-15.5-1.2 1.8 16.5-4.6 22.7-21.1 8-6.7 22-14.6 34.9-6 3.2-14.7-2.6-21.1-4-17.2-6.2-11.5 17.5-15.3 25.7-4 7.3-15.6 1.5-22.2-.2-26.7-10.8-55.1-3.1-82.4-.2-14.2 1.1-26 2.2-30.2 18.3-8 20.8-7.5 87.5-41.5 68.5-15.3-7.2-29.8-51.7-45.3-26.4-2.8 3.9-6.4 9.3-11.2 5.9-20.7-27.6-17-71-54.3-25.6-29.6 29.4-32.5 2.5-48.8-20.5-18.9-17.1-48.4-20.5-61.6-44.6-18.5-27.6-35.8-54.6-60.2-77.9-10.5-10.8-60.9-17.2-34.7-35.6 42.5-23.5-50.6-14-19.6-30.8 33.5-11.7 12.7-23.2-10.3-28.1-6.2-1.9-22-3.3-22.7-8.2 2.9-11.2 13.8-26.5 22.6-35.7 38.3-20.1-7-33.5-23.6-48.2-4-4.4 4.8-2.9 5.5-5.8-7.4-11.8-11.8-10-.4-21.8 3.2-7.8-4.9-17.6-3.8-25.5 8.1-21 57.9-6.5 64.2-36.2-3.5-26.1-16.4-50.3 3.5-75 5.9-8.8 22.4-16.8 19.3-28.7-5.7-14.7-26.4-23.7-27.6-40.2z"/><path d="m573 256.7s29.6-24.9 55-64.4 40.3-158 88.1-127.9c44.4 28-27.7 97.3-60.3 143.3-32.6 45.9-14.3 85.7-14.3 85.7l-68.5-36.6z"/><path d="m606.4 674.7s-11.3 37-11.2 84c0 47 51.9 154.6-4.6 155.3-52.5.6-29.6-96.8-27.1-153.1s-34.5-79.7-34.5-79.7z"/><path d="m325.5 622.7s-34 16.1-71.9 44c-37.8 27.9-104.9 118.2-126.8 89.7-20.3-26.5 66.8-72.5 113.1-104.6s51.2-64.9 51.2-64.9l34.4 35.9z"/><path d="m225.7 388.5s-30.8-35.1-75.8-72.7c-45.1-37.5-169.2-98.3-146.9-126.5 20.8-26.1 104.8 63 157.6 109.3 52.9 46.2 90.4 46.9 90.4 46.9l-25.4 43z"/><path d="m327.7 593.7s-47.6 1.4-103.9 17.7c-56.3 16.2-170.6 104.9-187.6 48.8-15.8-52.2 107.7-62.8 175.9-79.7s85.8-61.9 85.8-61.9l29.9 75.1z"/><path d="m443.5 344.2s0-46.7-8.9-104.6c-9-57.9-62-185.6-26.7-192 32.9-5.9 37 116.5 46.2 186.2 9.2 69.6 36.9 95 36.9 95l-47.5 15.5z"/><path d="m433.2 340.9s-6.8-37-19.5-82.8c-12.8-45.8-56.9-146.5-40.8-151.7 15-4.8 34.8 92 49.3 147s31.6 74.9 31.6 74.9l-20.6 12.5z"/><path d="m496.8 298.1s10.8-45.7 13.6-104.2c2.8-58.6-29.9-194.6 12.9-193.4 39.8 1.1 16.5 121.7 11.2 191.8-5.3 70 21.3 100.6 21.3 100.6l-59.1 5.2z"/><path d="m647.8 525s22.1 41.1 57.6 87.8c35.4 46.7 142.8 133.8 114.7 156.2-26.1 20.8-88-84.9-129.1-141.8-41.2-56.9-77.6-66-77.6-66z"/><path d="m658.4 523s23.5 29.3 56.5 63.5 119.7 101.9 108 114.1c-10.9 11.4-74.3-64.4-113.3-105.9s-63.4-50.9-63.4-50.9z"/><path d="m622.8 591s12.2 45.3 37.6 98.2 118.8 157 80.6 176.3c-35.6 17.9-72.4-99.3-101.1-163.4-28.6-64.1-66.6-78.4-66.6-78.4l49.5-32.6z"/><path d="m613.7 441.6s43.3 17.5 100.4 30.7c57.1 13.3 195.4 11.6 188.1 46.8-6.8 32.7-121.9-9.1-189.9-26.6s-101.9-1.2-101.9-1.2l3.3-49.8z"/><path d="m666.2 496.5s38.4 27.1 91.7 51.5 191.7 44.8 174.6 84.1c-15.9 36.5-119.1-30.1-182.2-61.1-63-31-101.3-17.7-101.3-17.7l17.2-56.7z"/><path d="m57.2 500.1c-7.1-1.3-14.4-2-21.5-.7-13.9 2.4-27.3 11.4-31.7 25.2-5 15.2 2.5 30.2 12.9 41.7 7.5 8.5 16.3 16.5 27.6 16.6 19.9-.7 36.3-19.9 37.6-39 1.6-18.3-8.2-36.2-27.2-40.2-3.5-.8-7.2-1.2-10.8-1.5"/><path d="m796.1 362.9c5.4 21.4 22.7 41 44.2 46.3 16.7 4.5 33.7-3 43.2-17.2 24.3-38.2-3-125.5-53.2-116.5-8 1.5-15.8 5.8-21.4 11.6-18.2 19.3-19.3 51.3-12.8 75.6z"/><path d="m255.1 782.9c5.4 21.4 22.7 41 44.2 46.3 16.7 4.5 33.7-3 43.2-17.2 24.3-38.2-3-125.5-53.2-116.5-8 1.5-15.8 5.8-21.4 11.6-18.2 19.3-19.3 51.3-12.8 75.6z"/><path d="m771 224.4c-3.4-.5-6.8-1-10.2-1.1-23.8-1.1-36.1 23.5-16.7 36.4 9.4 6.3 22.2 2.4 26.7-7.7 5.2-11.6-.7-20.3-10.6-26.9"/><path d="m402 812.4c-3.4-.5-6.8-1-10.2-1.1-23.8-1.1-36.1 23.5-16.7 36.4 9.4 6.3 22.2 2.4 26.7-7.7 5.2-11.6-.7-20.3-10.6-26.9"/></svg>
|
||||
<% end %>
|
||||
@@ -14,13 +15,18 @@
|
||||
<% end %>
|
||||
|
||||
<% if bubble.messages.comments.many? %>
|
||||
<span class="translucent txt-nowrap flex-item-no-shrink">(<%= bubble.messages.comments.count %>)</span>
|
||||
<span class="translucent txt-nowrap flex-item-no-shrink">
|
||||
<div aria-hidden="true">(<%= bubble.messages.comments.count %>)</div>
|
||||
<div class="for-screen-reader"><%= pluralize(bubble.messages.comments.count, "comment") %></div>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
<span class="flex-item-no-shrink flex">
|
||||
<span class="flex-item-no-shrink flex" role="group" aria-label="Assignees">
|
||||
<% bubble.assignees.each do |assignee| %>
|
||||
<%= link_to bubbles_path(@filter.as_params.merge(assignee_ids: [ assignee.id ])), class: "btn avatar", style: "font-size: 0.4em;" do %>
|
||||
<%= avatar_image_tag assignee, loading: :lazy %>
|
||||
<%= link_to bubbles_path(@filter.as_params.merge(assignee_ids: [ assignee.id ])),
|
||||
class: "btn avatar", style: "font-size: 0.4em;",
|
||||
aria: { label: assignee.name } do %>
|
||||
<%= avatar_image_tag assignee, loading: :lazy, aria: { hidden: true } %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</span>
|
||||
@@ -31,7 +37,8 @@
|
||||
|
||||
<% if bubble.due_on.present? %>
|
||||
<strong class="txt-nowrap txt-small" style="color: <%= bubble.color %>">
|
||||
<%= local_datetime_tag bubble.due_on, style: :shortdate %>
|
||||
<div class="for-screen-reader">Due on <%= local_datetime_tag bubble.due_on, style: :shortdate %></div>
|
||||
<div aria-hidden="true"><%= local_datetime_tag bubble.due_on, style: :shortdate %></div>
|
||||
</strong>
|
||||
<% end %>
|
||||
</div>
|
||||
@@ -41,4 +48,4 @@
|
||||
<span class="flex-item-no-shrink"><%= render "bubbles/tags", bubble: bubble %></span>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</li>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<li class="bubbles-list__divider flex align-center gap-half" draggable="true" data-divider-target="divider">
|
||||
<div class="divider-drag-image" data-divider-target="dragImage">Drag up or down</div>
|
||||
<hr class="separator--horizontal flex-item-grow">
|
||||
<hr class="separator--horizontal flex-item-grow" aria-hidden="true">
|
||||
<strong class="btn bubbles-list__count border-radius">
|
||||
<%= image_tag "drag.svg", aria: { hidden: true }, size: 24, class: "colorize--white" %>
|
||||
<span data-divider-target="count">10</span> Bubbled up
|
||||
</strong>
|
||||
<hr class="separator--horizontal flex-item-grow">
|
||||
<hr class="separator--horizontal flex-item-grow" aria-hidden="true">
|
||||
<span></span>
|
||||
</li>
|
||||
|
||||
@@ -56,11 +56,11 @@
|
||||
<%= form_with model: @bubble, url: bucket_bubble_path(@bubble.bucket, @bubble), data: { controller: "form" } do |form| %>
|
||||
<label class="btn full-width justify-start borderless min-width">
|
||||
<%= image_tag "picture-add.svg", aria: { hidden: true }, size: 24 %>
|
||||
<span class="overflow-ellipsis">Background</span>
|
||||
<%= form.file_field :image, class: "input",
|
||||
<span class="overflow-ellipsis" aria-hidden="true">Background</span>
|
||||
<%= form.file_field :image, class: "input visually-hidden",
|
||||
accept: "image/png, image/jpeg, image/jpg, image/webp",
|
||||
data: { action: "upload-preview#previewImage form#submit", upload_preview_target: "input" },
|
||||
hidden: true %>
|
||||
aria: { label: "Upload background image" },
|
||||
data: { action: "upload-preview#previewImage form#submit", upload_preview_target: "input" } %>
|
||||
</label>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<li class="bucket flex flex-column txt-align-center max-width">
|
||||
<%= link_to bubbles_path(bucket_ids: [ bucket ]), class: "border border-radius margin-block-end-half bubbles__container flex justify-center align-center position-relative" do %>
|
||||
<%= link_to bubbles_path(bucket_ids: [ bucket ]),
|
||||
class: "border border-radius margin-block-end-half bubbles__container flex justify-center align-center position-relative",
|
||||
aria: { hidden: true }, tabindex: -1 do %>
|
||||
<div class="bubbles bucket__bubbles flex flex-wrap gap justify-center align-end" style="view-transition-name: bubbles_<%= bucket.id %>">
|
||||
<% bucket.bubbles.active.published_or_drafted_by(Current.user).ordered_by_activity.limit(10).each do |bubble| %>
|
||||
<div class="<%= class_names("bubble", drafted: bubble.drafted?) %>" style="--bubble-color: <%= bubble.color %>; <%= bubble_rotation(bubble) %>"
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
</nav>
|
||||
<% end %>
|
||||
|
||||
<div class="buckets margin-block-double unpad align-start justify-center flex flex-wrap gap" data-controller="bubble-size">
|
||||
<ul class="buckets margin-block-double unpad align-start justify-center flex flex-wrap gap" data-controller="bubble-size">
|
||||
<%= render @buckets, cached: true %>
|
||||
</div>
|
||||
<div class="buckets margin-block-double unpad align-start justify-center flex flex-wrap gap" data-controller="bubble-size">
|
||||
</ul>
|
||||
<ul class="buckets margin-block-double unpad align-start justify-center flex flex-wrap gap" data-controller="bubble-size">
|
||||
<%= render @filters %>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
<%= render "notifications/tray" %>
|
||||
|
||||
@@ -2,12 +2,16 @@
|
||||
<%= turbo_frame_tag dom_id(comment) do %>
|
||||
<div class="comment__content flex-inline flex-column full-width border-radius">
|
||||
<div class="comment__author flex align-center gap-half">
|
||||
<strong><%= link_to comment.creator.name, user_path(comment.creator), class: "txt-ink btn btn--plain fill-transparent", data: { turbo_frame: "_top" } %></strong>
|
||||
<%= link_to bucket_bubble_path(comment.bubble.bucket, comment.bubble, anchor: "comment_#{comment.id}"), class: "txt-undecorated" do %>
|
||||
<%= local_datetime_tag comment.created_at, style: :shortdate, class: "comment__timestamp" %>
|
||||
<% end %>
|
||||
<h3 contents>
|
||||
<strong><%= link_to comment.creator.name, user_path(comment.creator), class: "txt-ink btn btn--plain fill-transparent", data: { turbo_frame: "_top" } %></strong>
|
||||
<%= link_to bucket_bubble_path(comment.bubble.bucket, comment.bubble, anchor: "comment_#{comment.id}"), class: "txt-undecorated" do %>
|
||||
<%= local_datetime_tag comment.created_at, style: :shortdate, class: "comment__timestamp" %>
|
||||
<% end %>
|
||||
</h3>
|
||||
|
||||
<%= link_to edit_bucket_bubble_comment_path(comment.bubble.bucket, comment.bubble, comment), class: "btn txt-small btn--plain fill-transparent comment__edit", style: "font-size: 0.4em; opacity: 0.5;" do %>
|
||||
<%= link_to edit_bucket_bubble_comment_path(comment.bubble.bucket, comment.bubble, comment), role: "button",
|
||||
class: "btn txt-small btn--plain fill-transparent comment__edit",
|
||||
style: "font-size: 0.4em; opacity: 0.5;" do %>
|
||||
<%= image_tag "menu-dots-horizontal.svg", class: "icon colorize--black" %>
|
||||
<span class="for-screen-reader">Edit</span>
|
||||
<% end %>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<%= comment_tag comment do %>
|
||||
<figure class="comment__avatar flex-item-no-shrink">
|
||||
<%= avatar_tag comment.creator, loading: :lazy %>
|
||||
<figure class="comment__avatar flex-item-no-shrink" aria-hidden="true">
|
||||
<%= avatar_tag comment.creator, hidden_for_screen_reader: true, loading: :lazy %>
|
||||
</figure>
|
||||
|
||||
<%= render "comments/body", comment: comment %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -5,14 +5,16 @@
|
||||
data-reaction-delete-reacter-id-value="<%= reaction.reacter.id %>"
|
||||
data-controller="reaction-delete" data-reaction-delete-perform-class="reaction--deleting"
|
||||
data-reaction-delete-reveal-class="expanded" data-reaction-delete-reacter-id-value="<%= reaction.reacter.id %>">
|
||||
<figure class="reaction__avatar margin-none flex-item-no-shrink">
|
||||
<%= avatar_tag reaction.reacter, aria: { label: "#{reaction.reacter.name} reacted #{reaction.content}" }, loading: :lazy %>
|
||||
<figure class="reaction__avatar margin-none flex-item-no-shrink" aria-hidden="true">
|
||||
<%= avatar_tag reaction.reacter, hidden_for_screen_reader: true, loading: :lazy %>
|
||||
</figure>
|
||||
|
||||
<%= tag.span reaction.content, role: "button",
|
||||
class: [ "txt-small", { "txt-medium": reaction.all_emoji? } ],
|
||||
data: { action: "click->reaction-delete#reveal keydown.enter->reaction-delete#reveal:prevent", reaction_delete_target: "content" } %>
|
||||
|
||||
<%= tag.span reaction.content, class: [ "txt-small", { "txt-medium": reaction.all_emoji? } ],
|
||||
data: {
|
||||
action: "click->reaction-delete#reveal keydown.enter->reaction-delete#reveal:prevent",
|
||||
reaction_delete_target: "content" } do %>
|
||||
<span class="for-screen-reader"><%= "#{reaction.reacter.name} reacted #{reaction.content}" %></span>
|
||||
<% end %>
|
||||
<%= button_to bucket_bubble_comment_reaction_path(comment.bubble.bucket, comment.bubble, comment, reaction),
|
||||
method: :delete,
|
||||
class: "btn btn--negative flex-item-justify-end reaction__delete",
|
||||
@@ -21,5 +23,4 @@
|
||||
<span class="for-screen-reader">Delete this reaction</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<span id="delete_reaction_accessible_label" class="for-screen-reader">Press enter to delete this reaction</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<%= turbo_frame_tag comment, :new_reaction do %>
|
||||
<div class="flex-inline" data-controller="soft-keyboard">
|
||||
<%= link_to new_bucket_bubble_comment_reaction_path(comment.bubble.bucket, comment.bubble, comment),
|
||||
<%= link_to new_bucket_bubble_comment_reaction_path(comment.bubble.bucket, comment.bubble, comment), role: "button",
|
||||
class: "txt-small btn reaction__action", action: "soft-keyboard#open" do %>
|
||||
<%= image_tag "reaction.svg", size: 20, aria: { hidden: "true" } %>
|
||||
<span class="for-screen-reader">Add a reaction</span>
|
||||
@@ -15,4 +15,4 @@
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<%= turbo_frame_tag dom_id(@comment, :new_reaction) do %>
|
||||
<%= form_with url: bucket_bubble_comment_reactions_path(@comment.bubble.bucket, @comment.bubble, @comment),
|
||||
class: "reaction reaction__form flex-inline postion--relative max-width align-center fill-white gap expanded",
|
||||
html: { aria: { label: "New reaction" } },
|
||||
data: { controller: "form", turbo_frame: dom_id(@comment, :reacting), action: "keydown.esc->form#cancel" } do |form| %>
|
||||
<label class="reaction__form-label flex gap" style="--column-gap: 0.7ch;" role="button" tabindex="0" aria-label="Add a reaction">
|
||||
<label class="reaction__form-label flex gap" style="--column-gap: 0.7ch;">
|
||||
<figure class="reaction__avatar margin-none flex-item-no-shrink">
|
||||
<%= avatar_tag Current.user %>
|
||||
<span class="for-screen-reader"><%= Current.user.name %></span>
|
||||
</figure>
|
||||
<%= form.text_field :content, name: "reaction[content]", autofocus: true, autocomplete: "off", autocorrect: "off", maxlength: 16,
|
||||
required: true, pattern: /\S+.*/, class: "input reaction__input txt-small" %>
|
||||
required: true, pattern: /\S+.*/, class: "input reaction__input txt-small",
|
||||
aria: { label: "Add a reaction" } %>
|
||||
</label>
|
||||
|
||||
<%= form.button class: "btn btn--reversed", type: "submit" do %>
|
||||
@@ -16,10 +17,10 @@
|
||||
<span class="for-screen-reader">Submit</span>
|
||||
<% end %>
|
||||
|
||||
<%= link_to bucket_bubble_comment_reactions_path(@comment.bubble.bucket, @comment.bubble, @comment),
|
||||
<%= link_to bucket_bubble_comment_reactions_path(@comment.bubble.bucket, @comment.bubble, @comment), role: "button",
|
||||
data: { turbo_frame: dom_id(@comment, :reactions), form_target: "cancel" }, class: "btn btn--negative" do %>
|
||||
<%= image_tag "minus.svg", aria: { hidden: "true" } %>
|
||||
<span class="for-screen-reader">Cancel</span>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -11,20 +11,22 @@
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow" data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="Assigned to…" aria-description="Assigned to…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half overflow-ellipsis">Assigned to…</strong>
|
||||
<%= form_with url: bubbles_path, method: :get, class: "flex flex-column full-width popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:assignee_ids, :assignment_status).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<%= link_to bubbles_path(filter.as_params.except(:assignee_ids, :assignment_status)), class: "btn popup__item" do %>
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "assignment_status", {
|
||||
<%= form.check_box :assignment_status, {
|
||||
checked: filter.assignment_status.unassigned?,
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
@@ -33,19 +35,20 @@
|
||||
<%= form.label :assignment_status, "No one", class: "overflow-ellipsis" %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 18, class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
|
||||
|
||||
<% Current.account.users.active.order(:name).each do |user| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "assignee_ids[]", {
|
||||
<%= form.check_box :assignee_ids, {
|
||||
multiple: true,
|
||||
checked: filter.assignees.include?(user),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, user.id %>
|
||||
|
||||
<%= form.label "assignee_ids[]", user.name, for: dom_id(user, :filter), class: "overflow-ellipsis" %>
|
||||
<%= form.label :assignee_ids, user.name, for: form.field_id(:assignee_ids, user.id), class: "overflow-ellipsis" %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 18, class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,31 +10,34 @@
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow" data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="In collection" aria-description="In collection"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half">In collection</strong>
|
||||
<%= form_with url: bubbles_path, method: :get, class: "flex flex-column full-width popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:bucket_ids).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<%= link_to bubbles_path(filter.as_params.except(:bucket_ids)), class: "btn popup__item" do %>
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% filter.buckets.order(:name).each do |bucket| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "bucket_ids[]", {
|
||||
<%= form.check_box :bucket_ids, {
|
||||
multiple: true,
|
||||
checked: filter.buckets.include?(bucket),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, bucket.id %>
|
||||
|
||||
<%= form.label "bucket_ids[]", bucket.name, for: dom_id(bucket, :filter), class: "overflow-ellipsis" %>
|
||||
<%= form.label :bucket_ids, bucket.name, for: form.field_id(:bucket_ids, bucket.id), class: "overflow-ellipsis" %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 18, class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -12,42 +12,45 @@
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
aria-label="Added by…" aria-description="Added by…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half">Added by…</strong>
|
||||
<%= form_with url: bubbles_path, method: :get, class: "flex flex-column full-width popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:creator_ids).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<%= link_to bubbles_path(filter.as_params.except(:creator_ids)), class: "btn popup__item" do %>
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "creator_ids[]", {
|
||||
<%= form.check_box :creator_ids, {
|
||||
multiple: true,
|
||||
checked: filter.creators.include?(Current.user),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, Current.user.id %>
|
||||
|
||||
<%= form.label "creator_ids[]", "Me", for: dom_id(Current.user, :creator_filter), class: "overflow-ellipsis" %>
|
||||
<%= form.label :creator_ids, "Me", for: form.field_id(:creator_ids, Current.user.id), class: "overflow-ellipsis" %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 18, class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
|
||||
|
||||
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "creator_ids[]", {
|
||||
<%= form.check_box :creator_ids, {
|
||||
multiple: true,
|
||||
checked: filter.creators.include?(user),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, user.id %>
|
||||
|
||||
<%= form.label "creator_ids[]", user.name, for: dom_id(user, :creator_filter), class: "overflow-ellipsis" %>
|
||||
<%= form.label :creator_ids, user.name, for: form.field_id(:creator_ids, user.id), class: "overflow-ellipsis" %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 18, class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<dialog class="filter__popup dialog panel fill-white shadow" data-dialog-target="dialog">
|
||||
<dialog class="filter__popup dialog panel fill-white shadow" aria-label="Filter" aria-description="Filter" data-dialog-target="dialog">
|
||||
<div class="flex flex-column gap-half">
|
||||
<div class="flex align-center gap-half justify-space-between">
|
||||
<span class="btn btn--placeholder txt-small" aria-hidden="true"></span>
|
||||
@@ -25,7 +25,7 @@
|
||||
<%= search_field_tag "terms[]", nil, class: "input full-width", placeholder: "By keyword…", id: nil %>
|
||||
|
||||
<button class="btn">
|
||||
<span class="for-screen-reader">Apply</span>
|
||||
<span class="for-screen-reader">Apply</span>
|
||||
<%= image_tag "arrow-right.svg", aria: { hidden: true }, size: 24 %>
|
||||
</button>
|
||||
<% end %>
|
||||
@@ -37,127 +37,130 @@
|
||||
<% end %>
|
||||
|
||||
<div class="filter__columns flex gap">
|
||||
<menu class="filter__menu">
|
||||
<li class="filter__label"><strong>Sort by</strong></li>
|
||||
<li>
|
||||
<%= label_tag "indexed_by_#{filter.default_indexed_by}", class: "btn filter__button" do %>
|
||||
<%= radio_button_tag "indexed_by", filter.default_indexed_by, filter.default_indexed_by?, hidden: true %>
|
||||
<div class="filter__menu" role="group" aria-label="Sort by">
|
||||
<div class="filter__label"><strong>Sort by</strong></div>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= radio_button_tag "indexed_by", filter.default_indexed_by, filter.default_indexed_by?, class: "visually-hidden" %>
|
||||
<span>Most active</span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<% Filter::INDEXES.each do |index| %>
|
||||
<li>
|
||||
<%= label_tag "indexed_by_#{index}", class: "btn filter__button" do %>
|
||||
<%= radio_button_tag "indexed_by", index, filter.indexed_by == index, hidden: true %>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= radio_button_tag "indexed_by", index, filter.indexed_by == index, class: "visually-hidden" %>
|
||||
<span><%= index.humanize %></span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</menu>
|
||||
</div>
|
||||
|
||||
<menu class="filter__menu">
|
||||
<li class="filter__label"><strong>In Collection</strong></li>
|
||||
<div class="filter__menu" role="group" aria-label="In Collection">
|
||||
<div class="filter__label"><strong>In Collection</strong></div>
|
||||
|
||||
<li>
|
||||
<div>
|
||||
<%= button_tag type: :button, class: "btn filter__button", data: { action: "filter-form#clearCategory", filter_form_name_param: "bucket_ids[]" } do %>
|
||||
<span>All Collections</span>
|
||||
<% end %>
|
||||
</li>
|
||||
</div>
|
||||
<% Current.user.buckets.order(:name).each do |bucket| %>
|
||||
<li>
|
||||
<%= label_tag "bucket_ids_#{bucket.id}", class: "btn filter__button" do %>
|
||||
<%= check_box_tag "bucket_ids[]", bucket.id, filter.buckets.include?(bucket), id: "bucket_ids_#{bucket.id}", hidden: true %>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "bucket_ids[]", bucket.id, filter.buckets.include?(bucket), class: "visually-hidden" %>
|
||||
<span><%= bucket.name %></span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</menu>
|
||||
</div>
|
||||
|
||||
<menu class="filter__menu">
|
||||
<li class="filter__label"><strong>Tagged</strong></li>
|
||||
<div class="filter__menu" role="group" aria-label="Tagged">
|
||||
<div class="filter__label"><strong>Tagged</strong></div>
|
||||
<% Current.account.tags.order(:title).each do |tag| %>
|
||||
<li>
|
||||
<%= label_tag "tag_ids_#{tag.id}", class: "btn filter__button" do %>
|
||||
<%= check_box_tag "tag_ids[]", tag.id, filter.tags.include?(tag), id: "tag_ids_#{tag.id}", hidden: true %>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "tag_ids[]", tag.id, filter.tags.include?(tag), class: "visually-hidden" %>
|
||||
<span><%= tag.hashtag %></span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</menu>
|
||||
</div>
|
||||
|
||||
<menu class="filter__menu">
|
||||
<li class="filter__label"><strong>Assigned to…</strong></li>
|
||||
<li>
|
||||
<%= label_tag "assignment_status_unassigned", class: "btn filter__button" do %>
|
||||
<%= check_box_tag "assignment_status", "unassigned", filter.assignment_status.unassigned?, id: "assignment_status_unassigned",
|
||||
hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignee_ids[],assigner_ids[]" } %>
|
||||
<span>No one</span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
<li>
|
||||
<%= label_tag "assignee_ids_me", class: "btn filter__button" do %>
|
||||
<%= check_box_tag "assignee_ids[]", Current.user.id, filter.assignees.include?(Current.user), id: "assignee_ids_me",
|
||||
hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignment_status" } %>
|
||||
<span>Me</span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
<div class="filter__menu" role="group" aria-label="Assigned to…">
|
||||
<div class="filter__label"><strong>Assigned to…</strong></div>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "assignment_status", "unassigned", filter.assignment_status.unassigned?,
|
||||
class: "visually-hidden",
|
||||
data: {
|
||||
action: "filter-form#clearCategory",
|
||||
filter_form_name_param: "assignee_ids[],assigner_ids[]" } %>
|
||||
<span>No one</span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "assignee_ids[]", Current.user.id, filter.assignees.include?(Current.user),
|
||||
class: "visually-hidden",
|
||||
data: { action: "filter-form#clearCategory", filter_form_name_param: "assignment_status" } %>
|
||||
<span>Me</span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
</label>
|
||||
</div>
|
||||
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
|
||||
<li>
|
||||
<%= label_tag "assignee_ids_#{user.id}", user.name, class: "btn filter__button" do %>
|
||||
<%= check_box_tag "assignee_ids[]", user.id, filter.assignees.include?(user), id: "assignee_ids_#{user.id}",
|
||||
hidden: true, data: { action: "filter-form#clearCategory", filter_form_name_param: "assignment_status" } %>
|
||||
<span><%= user.name %></span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% end %>
|
||||
</menu>
|
||||
|
||||
<menu class="filter__menu">
|
||||
<li class="filter__label"><strong>Added by…</strong></li>
|
||||
<li>
|
||||
<%= label_tag "creator_ids_me", class: "btn filter__button" do %>
|
||||
<%= check_box_tag "creator_ids[]", Current.user.id, filter.creators.include?(Current.user), id: "creator_ids_me",
|
||||
hidden: true %>
|
||||
<span>Me</span>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "assignee_ids[]", user.id, filter.assignees.include?(user), class: "visually-hidden",
|
||||
data: { action: "filter-form#clearCategory", filter_form_name_param: "assignment_status" } %>
|
||||
<span><%= user.name %></span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
|
||||
<li>
|
||||
<%= label_tag "creator_ids_#{user.id}", class: "btn filter__button" do %>
|
||||
<%= check_box_tag "creator_ids[]", user.id, filter.creators.include?(user), id: "creator_ids_#{user.id}",
|
||||
hidden: true %>
|
||||
<span><%= user.name %></span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</menu>
|
||||
</div>
|
||||
|
||||
<menu class="filter__menu">
|
||||
<li class="filter__label"><strong>In Stage</strong></li>
|
||||
<div class="filter__menu" role="group" aria-label="Added by…">
|
||||
<div class="filter__label"><strong>Added by…</strong></div>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "creator_ids[]", Current.user.id, filter.creators.include?(Current.user),
|
||||
class: "visually-hidden" %>
|
||||
<span>Me</span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
</label>
|
||||
</div>
|
||||
<% Current.account.users.active.without(Current.user).order(:name).each do |user| %>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "creator_ids[]", user.id, filter.creators.include?(user), class: "visually-hidden" %>
|
||||
<span><%= user.name %></span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<div class="filter__menu" role="group" aria-label="In Stage">
|
||||
<div class="filter__label"><strong>In Stage</strong></div>
|
||||
<% Current.account.workflows.order(:name).each do |workflow| %>
|
||||
<li class="filter__label"><strong><%= workflow.name %></strong></li>
|
||||
<div class="filter__label"><strong><%= workflow.name %></strong></div>
|
||||
|
||||
<% workflow.stages.order(:name).each do |stage| %>
|
||||
<li>
|
||||
<%= label_tag "stage_ids_#{stage.id}", class: "btn filter__button" do %>
|
||||
<%= check_box_tag "stage_ids[]", stage.id, filter.stages.include?(stage), id: "stage_ids_#{stage.id}", hidden: true %>
|
||||
<div>
|
||||
<label class="btn filter__button">
|
||||
<%= check_box_tag "stage_ids[]", stage.id, filter.stages.include?(stage), class: "visually-hidden" %>
|
||||
<span><%= stage.name %></span>
|
||||
<%= image_tag "close.svg", aria: { hidden: true }, size: 24 %>
|
||||
<% end %>
|
||||
</li>
|
||||
</label>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</menu>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<% cache_if filter.cacheable?, filter do %>
|
||||
<li class="bucket flex flex-column txt-align-center max-width position-relative">
|
||||
<%= link_to bubbles_path(**filter.as_params), class: "border border-radius margin-block-end-half bubbles__container flex justify-center align-center position-relative" do %>
|
||||
<%= link_to bubbles_path(**filter.as_params),
|
||||
class: "border border-radius margin-block-end-half bubbles__container flex justify-center align-center position-relative",
|
||||
aria: { hidden: true }, tabindex: -1 do %>
|
||||
<div class="bubbles bucket__bubbles flex flex-wrap gap justify-center align-end" style="view-transition-name: bubbles_<%= filter.id %>">
|
||||
<% filter.bubbles.ordered_by_activity.limit(10).each do |bubble| %>
|
||||
<div class="<%= class_names("bubble", drafted: bubble.drafted?) %>" style="--bubble-color: <%= bubble.color %>; <%= bubble_rotation(bubble) %>"
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow" data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="Sort by…" aria-description="Sort by…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half">Sort by…</strong>
|
||||
<%= form_with url: bubbles_path, method: :get, class: "flex flex-column full-width popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
@@ -35,4 +37,4 @@
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,35 +10,38 @@
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow" data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="In stage…" aria-description="In stage…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half">In stage…</strong>
|
||||
<%= form_with url: bubbles_path, method: :get, class: "flex flex-column full-width popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:stage_ids).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<%= link_to bubbles_path(filter.as_params.except(:stage_ids)), class: "btn popup__item" do %>
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% Current.account.workflows.order(:name).each do |workflow| %>
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half flex overflow-ellipsis"><%= workflow.name %></strong>
|
||||
|
||||
<% workflow.stages.order(:name).each do |stage| %>
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half flex overflow-ellipsis"><%= workflow.name %></strong>
|
||||
|
||||
<% workflow.stages.order(:name).each do |stage| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "stage_ids[]", {
|
||||
<%= form.check_box :stage_ids, {
|
||||
multiple: true,
|
||||
checked: filter.stages.include?(stage),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, stage.id %>
|
||||
|
||||
<%= form.label "stage_ids[]", stage.name, for: dom_id(stage, :filter), class: "overflow-ellipsis" %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 18, class: "checked flex-item-justify-end" %>
|
||||
<%= form.label :stage_ids, stage.name, for: form.field_id(:stage_ids, stage.id), class: "overflow-ellipsis" %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 18, class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@@ -9,30 +9,33 @@
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow" data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<dialog class="events__popup popup panel flex-column align-start gap-half fill-white shadow"
|
||||
aria-label="Tagged…" aria-description="Tagged…"
|
||||
data-dialog-target="dialog" data-action="turbo:before-cache@document->dialog#close">
|
||||
<strong class="popup__title margin-block-start-half pad-inline-half overflow-ellipsis">Tagged…</strong>
|
||||
<%= form_with url: bubbles_path, method: :get, class: "flex flex-column full-width popup__list",
|
||||
data: { controller: "form" } do |form| %>
|
||||
<% filter.as_params.except(:tag_ids).each do |key, value| %>
|
||||
<%= filter_hidden_field_tag key, value %>
|
||||
<% end %>
|
||||
|
||||
|
||||
<%= link_to bubbles_path(filter.as_params.except(:tag_ids)), class: "btn popup__item" do %>
|
||||
<span class="overflow-ellipsis">Clear all</span>
|
||||
<% end %>
|
||||
|
||||
|
||||
<% Current.account.tags.order(:title).each do |tag| %>
|
||||
<div class="btn popup__item">
|
||||
<%= form.check_box "tag_ids[]", {
|
||||
<%= form.check_box :tag_ids, {
|
||||
multiple: true,
|
||||
checked: filter.tags.include?(tag),
|
||||
data: { action: "change->form#submit" },
|
||||
include_hidden: false,
|
||||
}, tag.id %>
|
||||
|
||||
<%= form.label "tag_ids[]", tag.hashtag, for: dom_id(tag, :filter), class: "overflow-ellipsis" %>
|
||||
<%= form.label :tag_ids, tag.hashtag, for: form.field_id(:tag_ids, tag.id), class: "overflow-ellipsis" %>
|
||||
<%= image_tag "check.svg", aria: { hidden: true }, size: 18, class: "checked flex-item-justify-end" %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</dialog>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user