Commit Graph

5 Commits

Author SHA1 Message Date
Guillem Arias Fauste
25bb394378 fix(design-system): DS::Select a11y — fix aria-expanded, listbox keyboard nav, label binding (#1848)
* fix(design-system): DS::Select a11y — fix aria-expanded, listbox keyboard nav, label binding

Closes #1744. Several concrete bugs from the savings-goals audit:

1. **`aria-expanded` wired to the wrong state.** The template had
   `aria-expanded="<%= @selected_value.present? ? "true" : "false" %>"`,
   which is "has a value been chosen", not "is the menu open".
   AT users heard a misleading signal on every page load.
   Init to `"false"`; the Stimulus controller's openMenu/close
   already correctly maintains the attribute after that.

2. **`aria-labelledby` referenced a nonexistent id.** The trigger
   pointed at `"#{method}_label"`, but the rendered `<label>` had
   no id at all — the binding silently failed. Add
   `id: "#{method}_label"` to `form.label` so the reference
   actually resolves to the label text. Only emit
   `aria-labelledby` when there *is* a visible label.

3. **`tabindex="0"` on every option.** Listbox options should use
   roving tabindex (only the selected option is in tab order; the
   rest are reachable via ArrowUp/Down). Set
   `tabindex="0"` on the selected option only; `"-1"` on the rest.
   The select controller's `select()` handler keeps the roving
   invariant on user interaction.

4. **No keyboard navigation between options.** Add ArrowDown/Up
   (cycle), Home (first), End (last). The existing Enter/Escape
   handlers stay. ArrowUp/Down inside the search input is left
   alone so the input's caret behavior isn't hijacked.

5. **Search input had no accessible name.** Add an explicit
   `aria-label` matching the placeholder copy so AT users hear
   "search" when focus enters the field.

API unchanged. Builder-level routing fix in
`StyledFormBuilder#select` (calling DS::Select for `f.select(...)`
the same way `f.collection_select` already does) is intentionally
out of scope — it's a separate translation pass for the choices
format. Documented as a follow-up.

* fix(review): bridge search input to visible options in DS::Select

ArrowDown/Up from the search input now focus the first/last visible
option, and keyboard navigation operates on visible options only. After
typing a search query, the controller promotes the first visible option
to tabindex="0" so Tab can land on it even when the previously
tab-eligible option is filtered out.

Addresses Codex review on PR #1848 (issue #1744).

* fix(review): include trigger in DS::Select aria-labelledby

Codex P2 follow-up on #1848: \`aria-labelledby=\"#{method}_label\"\`
makes the trigger button's accessible name come solely from the
external form label — that overrides the button's own text node
(\`selected_item[:label]\` / placeholder). Screen readers therefore
announce only "Currency" without ever hearing the selected "USD"
unless the user opens the listbox.

Give the trigger \`id=\"#{method}_trigger\"\` and reference both ids:
\`aria-labelledby=\"#{method}_label #{method}_trigger\"\`. The
accessible-name algorithm concatenates the two, so AT users now
hear \"<Label> <selected value>\" while \`aria-expanded\` /
\`aria-haspopup\` continue to convey the dropdown state.
2026-05-20 18:19:58 +02:00
Pedro J. Aramburu
f699660479 Add exchange rate feature with multi-currency transactions and transfers support (#1099)
Co-authored-by: Pedro J. Aramburu <pedro@joakin.dev>
2026-04-08 21:05:58 +02:00
Tao Chen
2658c36b05 feat(select): improve merchant dropdown behavior and placement controls (#1364)
* feat(select): improve merchant dropdown behavior and placement controls

 - add configurable menu_placement strategy to DS::Select (auto/down/up) with safe normalization
forward menu_placement through StyledFormBuilder#collection_select
 - force Merchant dropdown to open downward in transaction create and editor forms
 - fix select option/search text contrast by applying text-primary in DS select menu
 - prevent form jump on open by scrolling only inside dropdown content instead of using scrollIntoView
 - clamp internal dropdown scroll to valid bounds for stability
- refactor select controller placement logic for readability (placementMode, clamp) without changing behavior

* set menu_placement=auto for metchant selector
2026-04-07 20:52:14 +02:00
sokiee
71c0735824 Linter 2026-03-22 10:48:54 +01:00
Alessio Cappa
0f78f54f90 New select component (#1071)
* feat: add new UI component to display dropdown select with filter

* feat: use new dropdown componet for category selection in transactions

* feat: improve dropdown controller

* feat: Add checkbox indicator to highlight selected element in list

* feat: add possibility to define dropdown without search

* feat: initial implementation of variants

* feat: Add default color for dropdown menu

* feat: add "icon" variant for dropdown

* refactor: component + controller refactoring

* refactor: view + component

* fix: adjust min width in selection for mobile

* feat: refactor collection_select method to use new filter dropdown component

* fix: compute fixed position for dropdown

* feat: controller improvements

* lint issues

* feat: add dot color if no icon is available

* refactor: controller refactor + update naming for variant from icon to logo

* fix: set width to 100% for select dropdown

* feat: add variant to collection_select in new transaction form

* fix: typo in placeholder value

* fix: add back include_blank property

* refactor: rename component from FilterDropdown to Select

* fix: translate placeholder and keep value_method and text_method

* fix: remove duplicate variable assignment

* fix: translate placeholder

* fix: verify color format

* fix: use right autocomplete value

* fix: selection issue + controller adjustments

* fix: move calls to startAutoUpdate and stopAutoUpdate

* Update app/javascript/controllers/select_controller.js

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>

* fix: add aria-labels

* fix: pass html_options to DS::Select

* fix: unnecessary closing tag

* fix: use offsetvalue for position checks

* fix: use right classes for dropdown transitions

* include options[:prompt] in placeholder init

* fix: remove unused locale key

* fix: Emit a native change event after updating the input value.

* fix: Guard against negative maxHeight in constrained layouts.

* fix: Update test

* fix: lint issues

* Update test/system/transfers_test.rb

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>

* Update test/system/transfers_test.rb

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>

* refactor: move CSS class for button select form in maybe-design-system.css

---------

Signed-off-by: Alessio Cappa <104093777+alessiocappa@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2026-03-06 10:16:14 +01:00