diff --git a/app/assets/stylesheets/card-perma.css b/app/assets/stylesheets/card-perma.css index 19138c0de..e589d4333 100644 --- a/app/assets/stylesheets/card-perma.css +++ b/app/assets/stylesheets/card-perma.css @@ -221,7 +221,7 @@ z-index: 1; } - .btn:not(.popup__item, .btn--plain, .btn--reversed) { + .btn:not(.popup__btn, .btn--plain, .btn--reversed) { --btn-background: var(--card-color); --btn-color: var(--color-ink-inverted); } diff --git a/app/assets/stylesheets/cards.css b/app/assets/stylesheets/cards.css index 1efff8c97..f0ae80af0 100644 --- a/app/assets/stylesheets/cards.css +++ b/app/assets/stylesheets/cards.css @@ -27,6 +27,10 @@ @media (prefers-color-scheme: dark) { box-shadow: 0 0 0 1px var(--color-ink-lighter); } + + .popup { + inline-size: 260px; + } } /* Header diff --git a/app/assets/stylesheets/fizzy-menu.css b/app/assets/stylesheets/fizzy-menu.css index 050a4fd9c..7eb992d1c 100644 --- a/app/assets/stylesheets/fizzy-menu.css +++ b/app/assets/stylesheets/fizzy-menu.css @@ -63,7 +63,7 @@ max-inline-size: 100%; /* When all its children are hidden, hide this as well so it doesn't take up space */ - &:has(.popup__group[hidden]):not(:has(.popup__group:not([hidden]))) { + &:has(.popup__item[hidden]):not(:has(.popup__item:not([hidden]))) { display: none; } diff --git a/app/assets/stylesheets/icons.css b/app/assets/stylesheets/icons.css index 356517f56..6eab28b1b 100644 --- a/app/assets/stylesheets/icons.css +++ b/app/assets/stylesheets/icons.css @@ -7,8 +7,9 @@ flex-shrink: 0; inline-size: var(--icon-size, 1em); mask-image: var(--svg); + mask-position: center; mask-repeat: no-repeat; - mask-size: cover; + mask-size: var(--icon-size, 1em); pointer-events: none; user-select: none; } diff --git a/app/assets/stylesheets/layout.css b/app/assets/stylesheets/layout.css index 634e306ec..f4157a270 100644 --- a/app/assets/stylesheets/layout.css +++ b/app/assets/stylesheets/layout.css @@ -20,6 +20,11 @@ max-inline-size: 100dvw; } + :where(#header) { + position: relative; + z-index: var(--z-nav); + } + :is(#header, #footer) { @media print { display: none; diff --git a/app/assets/stylesheets/popup.css b/app/assets/stylesheets/popup.css index 186bfa53e..c6035dedd 100644 --- a/app/assets/stylesheets/popup.css +++ b/app/assets/stylesheets/popup.css @@ -1,8 +1,11 @@ @layer components { .popup { + --btn-background: transparent; --panel-border-radius: 0.5em; --panel-padding: var(--block-space); --panel-size: auto; + --popup-icon-size: 24px; + --popup-item-padding-inline: var(--inline-space-half); inset: 0 auto auto 50%; max-block-size: 80vh; @@ -31,30 +34,71 @@ --panel-padding: var(--block-space) var(--block-space) 0 var(--block-space); } - .card & { - inline-size: 260px; + form { + display: contents; } } - #header:has(.popup) { - position: relative; - z-index: var(--z-nav); + .popup__title { + font-weight: 800; + white-space: nowrap; } - .popup__footer { - background-color: var(--color-canvas); - border-block-start: 1px solid var(--color-ink-lighter); + /* Hide lists when all the items within are hidden */ + .popup__section { + &:has(.popup__section-title:only-child), + &:has(.popup__item[hidden]):not(:has(.popup__item:not([hidden]))) { + display: none; + } + } + + .popup__section-title { + background: var(--color-canvas); font-size: var(--text-small); - inset: auto 0 0; - line-height: 1.6; - margin-block-start: var(--block-space-half); - padding: 1.5ch; + font-weight: bold; + list-style: none; + padding: var(--block-space-half) var(--inline-space-half); position: sticky; - text-align: center; + text-transform: uppercase; + top: calc(-1 * var(--block-space)); z-index: 1; + + &:is(summary) { + align-items: center; + cursor: pointer; + display: flex; + gap: 2ch; + justify-content: space-between; + } + + &::-webkit-details-marker { + display: none; + } + + .icon--caret-down { + opacity: 0.66; + transition: rotate 150ms ease-out; + } + + .popup__section:not([open]) & { + .icon--caret-down { + rotate: -90deg; + } + } } - .popup__group { + .popup__list { + display: flex; + flex-direction: column; + inline-size: 100%; + list-style: none; + margin: 0; + max-inline-size: 100%; + padding: 0; + row-gap: 1px; + } + + .popup__item { align-items: center; background: transparent; border-radius: 0.3em; @@ -62,14 +106,6 @@ inline-size: 100%; max-inline-size: 100%; - .popup__list &:has(*:first-child:not(.popup__item)) { - padding-inline-start: var(--inline-space-half); - } - - .btn { - --btn-background: transparent; - } - @media (any-hover: hover) { &:hover { background: var(--color-ink-lightest); @@ -85,52 +121,31 @@ } } } - } - .popup__list { - display: flex; - flex-direction: column; - inline-size: 100%; - list-style: none; - margin: 0; - max-inline-size: 100%; - padding: 0; - row-gap: 2px; + &:has(> :first-child:not(.popup__btn)) { + padding-inline-start: var(--popup-item-padding-inline); + } - /* Hide lists when all the items within are hidden */ - &:has(.popup__group-title:only-child), - &:has(.popup__group[hidden]):not(:has(.popup__group:not([hidden]))) { - display: none; + &:has(> :last-child:not(.popup__btn)) { + padding-inline-end: var(--popup-item-padding-inline); } } - .popup__item { - --btn-background: transparent; + /* The actionable thing with padding within popup__item */ + .popup__btn { --btn-border-radius: 0.3em; --btn-border-size: 0; - --btn-font-weight: 500; - --btn-padding: var(--inline-space-half) var(--inline-space); flex: 1 1 auto; + font-weight: 500; justify-content: start; inline-size: 100%; min-inline-size: 0; max-inline-size: 100%; + padding: var(--inline-space-half) var(--popup-item-padding-inline); text-align: start; - @media (any-hover: hover) { - &:where(:not(:active):hover) { - --btn-background: var(--color-selected); - } - } - - .icon { - block-size: 1em; - inline-size: 1em; - } - &:has(input:checked) { - --btn-background: transparent; --btn-color: var(--color-ink); .icon.checked { @@ -145,31 +160,40 @@ } } - .popup__new { - --btn-icon-size: 1em; + .popup__icon { + --icon-size: 1em; - padding-inline-start: var(--inline-space-half); + inline-size: var(--popup-icon-size); + } - .icon { - margin-inline-end: 0.5em; + .popup__radio { + --icon-size: var(--text-x-small); + + block-size: var(--popup-icon-size); + inline-size: var(--popup-icon-size); + flex-shrink: 0; + + &:hover { + --btn-border-color: var(--color-ink); } } - .popup__title { - font-weight: 800; - } - - .popup__group-title { - background: var(--color-canvas); + .popup__footer { + background-color: var(--color-canvas); + border-block-start: 1px solid var(--color-ink-lighter); font-size: var(--text-small); - font-weight: bold; - padding: var(--block-space-half) var(--inline-space-half); + inset: auto 0 0; + line-height: 1.6; + margin-block-start: var(--block-space-half); + padding: 1.5ch; position: sticky; - text-transform: uppercase; - top: calc(-1 * var(--block-space)); + text-align: center; z-index: 1; } + /* Variants + /* ------------------------------------------------------------------------ */ + .popup--animated { opacity: 0; transform: scale(0.2) translateX(-50%); diff --git a/app/helpers/filters_helper.rb b/app/helpers/filters_helper.rb index b6b95418b..797682c51 100644 --- a/app/helpers/filters_helper.rb +++ b/app/helpers/filters_helper.rb @@ -16,11 +16,10 @@ module FiltersHelper end def filter_place_menu_item(path, label, icon) - tag.li class: "popup__group", id: "filter-place-#{label.parameterize}", data: { filter_target: "item", navigable_list_target: "item" } do - concat icon_tag(icon) - concat(link_to(path, class: "popup__item btn") do + tag.li class: "popup__item", id: "filter-place-#{label.parameterize}", data: { filter_target: "item", navigable_list_target: "item" } do + concat icon_tag(icon, class: "popup__icon") + concat(link_to(path, class: "popup__btn btn") do concat tag.span(label, class: "overflow-ellipsis") - concat tag.span(" ›", class: "translucent flex-item-no-shrink flex-item-justify-end") end) end end @@ -36,8 +35,20 @@ module FiltersHelper }, &block end + def filter_collapsible_section(title, &block) + tag.details class: "popup__section", open: true do + concat(tag.summary(class: "popup__section-title") do + concat title + concat icon_tag "caret-down" + end) + concat(tag.ul(class: "popup__list") do + capture(&block) + end) + end + end + def filter_hotkey_link(title, path, key, icon) - link_to path, class: "popup__group btn borderless", id: "filter-hotkey-#{key}", role: "listitem", data: { filter_target: "item", navigable_list_target: "item", controller: "hotkey", action: "keydown.#{key}@document->hotkey#click keydown.shift+#{key}@document->hotkey#click" } do + link_to path, class: "popup__item btn borderless", id: "filter-hotkey-#{key}", role: "listitem", data: { filter_target: "item", navigable_list_target: "item", controller: "hotkey", action: "keydown.#{key}@document->hotkey#click keydown.shift+#{key}@document->hotkey#click" } do concat icon_tag(icon) concat tag.span(title.html_safe) concat tag.kbd(key) diff --git a/app/views/cards/assignments/new.html.erb b/app/views/cards/assignments/new.html.erb index 69c499524..0c16aa94d 100644 --- a/app/views/cards/assignments/new.html.erb +++ b/app/views/cards/assignments/new.html.erb @@ -5,7 +5,7 @@ dialog_target: "dialog", navigable_list_focus_on_selection_value: false, navigable_list_actionable_items_value: true } do %> - Assign this to… + Assign this to… <% if @collection.users.active.count > 1 %> <%= text_field_tag :search, nil, placeholder: "Filter…", class: "input input--transparent txt-small margin-block-half", autofocus: true, @@ -14,9 +14,9 @@