Wire-up keyboard navigation

- Introduces a distinct controller and individual forms for each option so they behave like other pop-ups
- Adds `filter` and `navigable-list` behaviors
This commit is contained in:
Jason Zimdars
2025-06-03 11:05:39 -05:00
parent acfc7da551
commit ff403021cc
4 changed files with 32 additions and 22 deletions
+1
View File
@@ -27,6 +27,7 @@
.txt-link { color: var(--color-link); text-decoration: underline; }
.font-black { font-weight: 900; }
.font-weight-normal { font-weight: normal; }
/* Flexbox and Grid */
.justify-end { justify-content: end; }
@@ -0,0 +1,9 @@
module Cards
class CollectionsController < ApplicationController
def update
@card = Card.find(params[:card_id])
@card.update!(collection_id: params[:collection_id])
redirect_to @card
end
end
end
@@ -1,5 +1,5 @@
<%= render "cards/display/common/collection", card: card do %>
<div class="position-relative" data-controller="dialog" data-action="keydown.esc->dialog#close:stop click@document->dialog#closeOnClickOutside" <%= "hidden" if card.closed? %>>
<div class="position-relative txt-small" data-controller="dialog" data-action="keydown.esc->dialog#close:stop click@document->dialog#closeOnClickOutside" <%= "hidden" if card.closed? %>>
<button class="collection-picker__button btn btn--reversed card__hide-on-index fill-transparent" data-action="click->dialog#open:stop">
<%= icon_tag "caret-down" %>
<span class="for-screen-reader">Choose a collection for this card</span>
@@ -7,31 +7,30 @@
<dialog class="popup panel flex-column align-start gap-half fill-white shadow" data-dialog-target="dialog">
<%= tag.div class: "max-width full-width", data: {
controller: "filter",
action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset",
controller: "filter navigable-list",
dialog_target: "dialog",
filter_active_class: "filter--active",
filter_selected_class: "selected"} do %>
<strong class="popup__title pad-inline-half txt-nowrap">Put this card in…</strong>
navigable_list_focus_on_selection_value: false,
navigable_list_actionable_items_value: true } do %>
<strong class="popup__title pad-inline-half txt-nowrap">Move this card to…</strong>
<% if Current.user.collections.count > 20 %>
<input placeholder="Find a collection…" class="input input--transparent txt-small margin-block-half" type="search" autocorrect="off" autocomplete="off" data-1p-ignore="true" data-action="input->filter#filter" autofocus>
<% if Current.user.collections.count > 1 %>
<%= text_field_tag :search, nil, placeholder: "Filter…", class: "input input--transparent txt-small margin-block-half font-weight-normal", autofocus: true,
type: "search", autocorrect: "off", autocomplete: "off", data: { "1p-ignore": "true", filter_target: "input", action: "input->filter#filter" } %>
<% end %>
<%= form_with(model: card, url: collection_card_path(card.collection, card), method: :patch, class: "full-width", data: { controller: "form" }) do |form| %>
<ul class="flex flex-column full-width popup__list margin-block-start-half margin-none-inline margin-none-block-end unpad max-width" data-filter-target="list">
<% Current.user.collections.alphabetically.each do |collection| %>
<li class="popup__group flex align-center full-width" data-value="<%= collection.name.downcase %>">
<label class="btn popup__item min-width flex-item-grow full-width unpad-inline">
<%= form.radio_button :collection_id, collection.id,
class: "visually-hidden",
data: { action: "change->form#submit" } %>
<span class="overflow-ellipsis flex-item-grow"><%= collection.name %></span>
<%= icon_tag "check", size: 18, class: "checked flex-item-no-shrink flex-item-justify-end", style: "--icon-size: 1em" if card.collection == collection %>
</label>
</li>
<% end %>
</ul>
<% end %>
<ul class="flex flex-column full-width popup__list margin-block-start-half margin-none-inline margin-none-block-end unpad max-width" data-filter-target="list">
<% Current.user.collections.alphabetically.each do |collection| %>
<li class="popup__group flex align-center full-width" data-value="<%= collection.name.downcase %>" data-filter-target="item" data-navigable-list-target="item">
<%= button_to card_collection_path(card, params: { collection_id: collection.id }), method: :patch,
class: "btn popup__item min-width flex-item-grow full-width unpad-inline",
form_class: "max-width flex-item-grow" do %>
<span class="overflow-ellipsis flex-item-grow"><%= collection.name %></span>
<%= icon_tag "check", size: 18, class: "checked flex-item-no-shrink flex-item-justify-end", style: "--icon-size: 1em" if card.collection == collection %>
<% end %>
</li>
<% end %>
</ul>
<% end %>
</dialog>
</div>
+1
View File
@@ -35,6 +35,7 @@ Rails.application.routes.draw do
resource :recover
resource :staging
resource :watch
resource :collection, only: :update
resources :assignments
resources :taggings