From 27a99b4e1d1b9069efca3995de78d0b08317bd51 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Mon, 15 Sep 2025 16:29:32 -0500 Subject: [PATCH 1/7] Remember nav section collapsed state --- app/helpers/filters_helper.rb | 4 +-- .../nav_section_expander_controller.js | 26 +++++++++++++++++++ app/views/filters/menu/_collections.html.erb | 2 +- app/views/filters/menu/_custom.html.erb | 2 +- app/views/filters/menu/_places.html.erb | 2 +- app/views/filters/menu/_tags.html.erb | 2 +- app/views/filters/menu/_users.html.erb | 2 +- 7 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 app/javascript/controllers/nav_section_expander_controller.js diff --git a/app/helpers/filters_helper.rb b/app/helpers/filters_helper.rb index 797682c51..13ff3ec4d 100644 --- a/app/helpers/filters_helper.rb +++ b/app/helpers/filters_helper.rb @@ -35,8 +35,8 @@ module FiltersHelper }, &block end - def filter_collapsible_section(title, &block) - tag.details class: "popup__section", open: true do + def collapsible_nav_section(title, &block) + tag.details class: "popup__section", data: { controller: "nav-section-expander", action: "toggle->nav-section-expander#toggle", nav_section_expander_key_value: title.parameterize }, open: true do concat(tag.summary(class: "popup__section-title") do concat title concat icon_tag "caret-down" diff --git a/app/javascript/controllers/nav_section_expander_controller.js b/app/javascript/controllers/nav_section_expander_controller.js new file mode 100644 index 000000000..930b8760e --- /dev/null +++ b/app/javascript/controllers/nav_section_expander_controller.js @@ -0,0 +1,26 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static values = { key: String } + + connect() { + this.#restoreToggle() + } + + toggle() { + if (this.element.open) { + localStorage.removeItem(this.#localStorageKey) + } else { + localStorage.setItem(this.#localStorageKey, this.keyValue) + } + } + + #restoreToggle() { + const isCollapsed = localStorage.getItem(this.#localStorageKey) != null + if (isCollapsed) this.element.open = false + } + + get #localStorageKey() { + return this.keyValue + } +} diff --git a/app/views/filters/menu/_collections.html.erb b/app/views/filters/menu/_collections.html.erb index c43ce3f23..c9298093e 100644 --- a/app/views/filters/menu/_collections.html.erb +++ b/app/views/filters/menu/_collections.html.erb @@ -2,7 +2,7 @@ <%= form_with url: user_filtering.self_filter_path(script_name: Account.sole.slug), method: :get, class: "display-contents", data: { controller: "form" } do |form| %> <% if user_filtering.collections.any? %> - <%= filter_collapsible_section "Collections" do %> + <%= collapsible_nav_section "Collections" do %> <%= render "filters/menu/collections/all_option", form: form, user_filtering: user_filtering %> <%= render partial: "filters/menu/collections/collection", collection: user_filtering.collections, as: :collection, locals: { form: form, user_filtering: user_filtering } %> <% end %> diff --git a/app/views/filters/menu/_custom.html.erb b/app/views/filters/menu/_custom.html.erb index e9e061345..2de2cae1d 100644 --- a/app/views/filters/menu/_custom.html.erb +++ b/app/views/filters/menu/_custom.html.erb @@ -1,4 +1,4 @@ -<%= filter_collapsible_section "Saved filters" do %> +<%= collapsible_nav_section "Saved filters" do %> <%= form_with url: cards_path, method: :get, data: { controller: "form" } do |form| %> <%= render "filters/menu/custom/create" %> <%= render partial: "filters/menu/custom/filter", collection: user_filtering.filters, as: :filter, locals: { user_filtering: user_filtering } %> diff --git a/app/views/filters/menu/_places.html.erb b/app/views/filters/menu/_places.html.erb index 0bf30d8e4..26a05b2be 100644 --- a/app/views/filters/menu/_places.html.erb +++ b/app/views/filters/menu/_places.html.erb @@ -1,4 +1,4 @@ -<%= filter_collapsible_section "Jump to…" do %> +<%= collapsible_nav_section "Jump to…" do %> <%= filter_place_menu_item account_settings_path, "Account Settings", "settings" %> <%= filter_place_menu_item user_path(Current.user), "My Profile", "person" %> <%= filter_place_menu_item notifications_path, "Notifications", "bell" %> diff --git a/app/views/filters/menu/_tags.html.erb b/app/views/filters/menu/_tags.html.erb index 1b2c27c86..104d6f29f 100644 --- a/app/views/filters/menu/_tags.html.erb +++ b/app/views/filters/menu/_tags.html.erb @@ -1,3 +1,3 @@ -<%= filter_collapsible_section "Tags" do %> +<%= collapsible_nav_section "Tags" do %> <%= render partial: "filters/menu/tags/tag", collection: user_filtering.tags, as: :tag %> <% end %> diff --git a/app/views/filters/menu/_users.html.erb b/app/views/filters/menu/_users.html.erb index cbc88ce98..fc2dff5ee 100644 --- a/app/views/filters/menu/_users.html.erb +++ b/app/views/filters/menu/_users.html.erb @@ -1,3 +1,3 @@ -<%= filter_collapsible_section "People" do %> +<%= collapsible_nav_section "People" do %> <%= render partial: "filters/menu/users/user", collection: user_filtering.users, as: :user %> <% end %> From 3cad86411f5e4d342a522198c826192744901788 Mon Sep 17 00:00:00 2001 From: Andy Smith Date: Tue, 16 Sep 2025 14:14:38 -0500 Subject: [PATCH 2/7] WIP --- app/assets/stylesheets/filters.css | 1 - app/assets/stylesheets/popup.css | 14 ++++++- app/helpers/filters_helper.rb | 2 +- .../controllers/filter_controller.js | 2 +- .../nav_section_expander_controller.js | 40 +++++++++++++++++-- app/views/filters/_menu.html.erb | 4 +- app/views/my/menus/show.html.erb | 1 + 7 files changed, 55 insertions(+), 9 deletions(-) diff --git a/app/assets/stylesheets/filters.css b/app/assets/stylesheets/filters.css index d0680c86a..8ce52d66c 100644 --- a/app/assets/stylesheets/filters.css +++ b/app/assets/stylesheets/filters.css @@ -11,7 +11,6 @@ } .filters { - .btn { --btn-border-color: var(--color-ink-medium); --input-background: var(--color-canvas); diff --git a/app/assets/stylesheets/popup.css b/app/assets/stylesheets/popup.css index c6035dedd..ba5be2a54 100644 --- a/app/assets/stylesheets/popup.css +++ b/app/assets/stylesheets/popup.css @@ -45,11 +45,23 @@ } /* Hide lists when all the items within are hidden */ - .popup__section { + /* .popup__section { &:has(.popup__section-title:only-child), &:has(.popup__item[hidden]):not(:has(.popup__item:not([hidden]))) { display: none; } + } */ + + .popup__section { + .popup__section-title { + background: orange; + } + + &[open] { + .popup__section-title { + background: lime; + } + } } .popup__section-title { diff --git a/app/helpers/filters_helper.rb b/app/helpers/filters_helper.rb index 13ff3ec4d..337c7e2d4 100644 --- a/app/helpers/filters_helper.rb +++ b/app/helpers/filters_helper.rb @@ -36,7 +36,7 @@ module FiltersHelper end def collapsible_nav_section(title, &block) - tag.details class: "popup__section", data: { controller: "nav-section-expander", action: "toggle->nav-section-expander#toggle", nav_section_expander_key_value: title.parameterize }, open: true do + tag.details class: "popup__section", data: { controller: "nav-section-expander", action: "toggle->nav-section-expander#toggle", nav_section_expander_target: "section", nav_section_expander_key_value: title.parameterize }, open: true do concat(tag.summary(class: "popup__section-title") do concat title concat icon_tag "caret-down" diff --git a/app/javascript/controllers/filter_controller.js b/app/javascript/controllers/filter_controller.js index 688c46155..7f3770a8e 100644 --- a/app/javascript/controllers/filter_controller.js +++ b/app/javascript/controllers/filter_controller.js @@ -11,7 +11,7 @@ export default class extends Controller { filter() { this.itemTargets.forEach(item => { - if (filterMatches(item.innerText, this.inputTarget.value)) { + if (filterMatches(item.textContent, this.inputTarget.value)) { item.removeAttribute("hidden") } else { item.toggleAttribute("hidden", true) diff --git a/app/javascript/controllers/nav_section_expander_controller.js b/app/javascript/controllers/nav_section_expander_controller.js index 930b8760e..c1642fcb2 100644 --- a/app/javascript/controllers/nav_section_expander_controller.js +++ b/app/javascript/controllers/nav_section_expander_controller.js @@ -1,21 +1,51 @@ import { Controller } from "@hotwired/stimulus" +// TODO: roll up this controller to one level; remove from sections +// This will involve using events to select the sections when they're clicked + export default class extends Controller { static values = { key: String } + static targets = [ "input" ] connect() { this.#restoreToggle() } toggle() { - if (this.element.open) { - localStorage.removeItem(this.#localStorageKey) + console.log(this.element) + if (this.element.hasAttribute("data-ignore")) { + // console.log("Don't save it!") } else { - localStorage.setItem(this.#localStorageKey, this.keyValue) + // console.log("Save it!") + if (this.element.open) { + localStorage.removeItem(this.#localStorageKey) + } else { + localStorage.setItem(this.#localStorageKey, this.keyValue) + } + } + } + + // OK, here's the behavior we want: + // Open the dialog, and the sections are in various states of collapsed/open. + // When you filter, we open them all. + // When the filter is empty, we need to go back to the saved state. + showAll() { + console.log(this.element) + // When filtering, we open everything and don't save to local storage. + // When the filter is cleared, we restore toggles + if (this.inputTarget.value) { + for (const section of this.#sections) { + section.setAttribute("data-ignore", true) + section.setAttribute("open", true) + } + } else { + // UGH! This works in the context of the controller on the section, not from the birds-eye view of the details el. + this.#restoreToggle() } } #restoreToggle() { + // console.log("RESTORE TOGGLE") const isCollapsed = localStorage.getItem(this.#localStorageKey) != null if (isCollapsed) this.element.open = false } @@ -23,4 +53,8 @@ export default class extends Controller { get #localStorageKey() { return this.keyValue } + + get #sections() { + return this.element.querySelectorAll(":scope details:not([open])") + } } diff --git a/app/views/filters/_menu.html.erb b/app/views/filters/_menu.html.erb index 42079fe05..95c4b29dc 100644 --- a/app/views/filters/_menu.html.erb +++ b/app/views/filters/_menu.html.erb @@ -3,8 +3,8 @@ <%= tag.dialog class: "fizzy-menu filter popup popup--animated panel margin-block-start-half", data: { - action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset toggle->filter#filter", - controller: "filter navigable-list", + action: "turbo:before-cache@document->dialog#close keydown->navigable-list#navigate filter:changed->navigable-list#reset filter:changed->nav-section-expander#showAll toggle->filter#filter", + controller: "filter navigable-list nav-section-expander", dialog_target: "dialog", navigable_list_focus_on_selection_value: false, navigable_list_actionable_items_value: true } do %> diff --git a/app/views/my/menus/show.html.erb b/app/views/my/menus/show.html.erb index 05a50c290..90a784ce3 100644 --- a/app/views/my/menus/show.html.erb +++ b/app/views/my/menus/show.html.erb @@ -12,6 +12,7 @@ data: { "1p-ignore": "true", filter_target: "input", + nav_section_expander_target: "input", navigable_list_target: "input", action: "input->filter#filter" } %>