✨ Voting-Booth: Collapsed by default Lists#479
Conversation
There was a problem hiding this comment.
Pull request overview
Adds “collapsed by default” behavior for category lists in the Voting Booth simultaneous-questions v2 UI, including per-category collapse/expand and an Expand/Collapse All control, with updated translations.
Changes:
- Initialize question categories as collapsed by default and auto-expand matched categories during search.
- Add an Expand/Collapse All button to the question header area.
- Make category headers clickable/keyboard-accessible to toggle collapse, and add i18n strings for the new labels.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
locales/en.json |
Adds collapseAll / expandAll strings for the new UI control. |
locales/es.json |
Adds collapseAll / expandAll strings for the new UI control. |
locales/fr.json |
Adds collapseAll / expandAll strings for the new UI control. |
locales/it.json |
Adds collapseAll / expandAll strings for the new UI control. |
locales/ca.json |
Adds collapseAll / expandAll strings for the new UI control. |
avBooth/simultaneous-questions-v2-screen-directive/simultaneous-questions-v2-screen-directive.js |
Introduces isCollapsed state per category and search-driven expand/collapse behavior; adds “toggle all” helpers. |
avBooth/simultaneous-questions-v2-screen-directive/simultaneous-questions-v2-screen-directive.html |
Renders the Expand/Collapse All button in the question header UI. |
avBooth/simultaneous-questions-v2-screen-directive/simultaneous-questions-v2-screen-directive.less |
Styles the new button and changes header layout. |
avBooth/simultaneous-questions-category-v2-directive/simultaneous-questions-category-v2-directive.js |
Adds a toggleCollapse helper for keyboard interaction. |
avBooth/simultaneous-questions-category-v2-directive/simultaneous-questions-category-v2-directive.html |
Makes category headers toggleable (mouse/keyboard), adds chevron indicator, and hides body when collapsed. |
avBooth/simultaneous-questions-category-v2-directive/simultaneous-questions-category-v2-directive.less |
Adds interactive styling for the clickable header and chevron. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .question-search-container { | ||
| width: 100%; | ||
| display: flex; | ||
| flex-direction: row; | ||
| justify-content: flex-end; | ||
| justify-content: space-between; | ||
| align-items: center; | ||
| margin-bottom: 12px; |
There was a problem hiding this comment.
Changing .question-search-container to justify-content: space-between will left-align the search/filter control on questions without categories (because the collapse/expand button is not rendered). This is a UI regression vs the previous flex-end behavior. Consider keeping flex-end by default and only using space-between when the collapse/expand button is present (e.g., via a conditional class) so the filter stays right-aligned when it’s the only child.
| ng-attr-tabindex="{{ !isReview ? '0' : undefined }}" | ||
| ng-attr-role="{{ !isReview ? 'button' : undefined }}" | ||
| ng-attr-aria-expanded="{{ !isReview ? !category.isCollapsed : undefined }}" | ||
| ng-keydown="($event.key === 'Enter' || $event.key === ' ') && toggleCollapse() && $event.preventDefault()" |
There was a problem hiding this comment.
ng-keydown relies on toggleCollapse() being truthy to reach $event.preventDefault(), but toggleCollapse currently returns undefined, so default key behavior (notably Space scrolling) won’t be prevented. Adjust the handler so preventDefault() always runs when handling Enter/Space (e.g., call both statements unconditionally in the expression, or have toggleCollapse return true).
| ng-keydown="($event.key === 'Enter' || $event.key === ' ') && toggleCollapse() && $event.preventDefault()" | |
| ng-keydown="($event.key === 'Enter' || $event.key === ' ') && toggleCollapse(); ($event.key === 'Enter' || $event.key === ' ') && $event.preventDefault()" |
| class="category-heading" | ||
| id="question_{{question.index}}_answer_{{category.categoryAnswer.id}}" | ||
| ng-click="!isReview && (category.isCollapsed = !category.isCollapsed)" | ||
| ng-attr-tabindex="{{ !isReview ? '0' : undefined }}" | ||
| ng-attr-role="{{ !isReview ? 'button' : undefined }}" | ||
| ng-attr-aria-expanded="{{ !isReview ? !category.isCollapsed : undefined }}" | ||
| ng-keydown="($event.key === 'Enter' || $event.key === ' ') && toggleCollapse() && $event.preventDefault()" |
There was a problem hiding this comment.
The collapse toggle logic is duplicated: ng-click toggles category.isCollapsed inline, while keyboard handling calls toggleCollapse(). This can drift over time (and already adds an extra review guard in JS). Consider using toggleCollapse() for both click and keydown so there is a single source of truth for the interaction behavior.
| &:hover, &:focus { | ||
| opacity: 0.85; | ||
| outline: none; | ||
| } | ||
|
|
||
| &:focus-visible { | ||
| outline: 2px solid @av-primary-contrast; | ||
| border-radius: 3px; | ||
| } |
There was a problem hiding this comment.
:focus { outline: none; } removes the keyboard focus indicator unless the browser supports :focus-visible. Since :focus-visible support is not universal, this can make the heading unreachable for keyboard users. Prefer keeping an outline for :focus (or providing a non-:focus-visible fallback) so focus is always visible.
| &:hover, &:focus { | |
| opacity: 0.85; | |
| outline: none; | |
| } | |
| &:focus-visible { | |
| outline: 2px solid @av-primary-contrast; | |
| border-radius: 3px; | |
| } | |
| &:hover { | |
| opacity: 0.85; | |
| } | |
| &:focus { | |
| opacity: 0.85; | |
| outline: 2px solid @av-primary-contrast; | |
| border-radius: 3px; | |
| } | |
| &:focus:not(:focus-visible) { | |
| outline: none; | |
| } |
| cursor: pointer; | ||
| user-select: none; | ||
|
|
||
| &:hover, &:focus { | ||
| opacity: 0.85; | ||
| outline: none; | ||
| } | ||
|
|
||
| &:focus-visible { | ||
| outline: 2px solid @av-primary-contrast; | ||
| border-radius: 3px; |
There was a problem hiding this comment.
.category-heading is styled with cursor: pointer even in review mode where the heading is not interactive (no role="button", click is gated by !isReview). This can mislead users into thinking it’s clickable. Consider scoping the pointer/hover styles to the interactive state only (e.g., when it has role="button" or a dedicated class set only when !isReview).
| cursor: pointer; | |
| user-select: none; | |
| &:hover, &:focus { | |
| opacity: 0.85; | |
| outline: none; | |
| } | |
| &:focus-visible { | |
| outline: 2px solid @av-primary-contrast; | |
| border-radius: 3px; | |
| &[role="button"] { | |
| cursor: pointer; | |
| user-select: none; | |
| &:hover, &:focus { | |
| opacity: 0.85; | |
| outline: none; | |
| } | |
| &:focus-visible { | |
| outline: 2px solid @av-primary-contrast; | |
| border-radius: 3px; | |
| } |
PR: https://github.com/sequentech/meta/issues/11123