Skip to content

DS Drift Patrol — 1 finding (week of 2026-06-18) #2404

Description

@sure-design

DS Drift Patrol — 1 finding

Scan period: 2026-06-11 → 2026-06-18 (commits merged to main)
Open PRs scanned: 20 open PRs — all CLEAN
Merged commits scanned: 9 UI-relevant commits — 1 violation


Finding 1 — Rule 1: Raw <details> bypasses DS::Disclosure

Commit: c29380cefeat(dashboard): masonry packing + per-widget size controls (#2328) (merged 2026-06-15)
File: app/views/pages/dashboard.html.erb

Introduced + lines:

<details
  class="relative hidden lg:block"
  data-controller="dashboard-widget-size"
  data-dashboard-widget-size-section-key-value="<%= section[:key] %>"
  data-action="keydown->dashboard-widget-size#stopKeydown">
  <summary
    class="focus-ring list-none cursor-pointer text-secondary hover:text-primary transition-colors p-0.5 opacity-0 group-hover:opacity-100 [&::-webkit-details-marker]:hidden"
    aria-label="<%= t("pages.dashboard.widget_size.label") %>">
    <%= icon("sliders-horizontal", size: "sm", class: "!w-3.5 !h-3.5") %>
  </summary>
  <div class="absolute right-0 top-full mt-1.5 z-10 w-48 p-2.5 space-y-2.5 bg-surface rounded-xl shadow-border-xs border border-primary">
    ...
  </div>
</details>

Rule broken: Raw <details>/<summary> element used instead of DS::Disclosure.

Good news — the fix is already available: Commit beec50b4 (merged the same day, 2026-06-15) added a body_class: option to DS::Disclosure specifically to handle this pattern — pass body_class: nil to suppress the mt-2 body wrapper for absolutely-positioned popovers. This is exactly the mechanism needed for the size menu.

Suggested fix:

<%= render DS::Disclosure.new(
      body_class: nil,
      data: {
        controller: "dashboard-widget-size",
        dashboard_widget_size_section_key_value: section[:key],
        action: "keydown->dashboard-widget-size#stopKeydown"
      }) do |disclosure| %>
  <% disclosure.with_summary_content do %>
    <span class="sr-only"><%= t("pages.dashboard.widget_size.label") %></span>
    <%= icon("sliders-horizontal", size: "sm", class: "!w-3.5 !h-3.5") %>
  <% end %>
  <div class="absolute right-0 top-full mt-1.5 z-10 w-48 p-2.5 space-y-2.5 bg-surface rounded-xl shadow-border-xs border border-primary">
    ...
  </div>
<% end %>

The summary can be made accessible either via aria-label on the <summary> element or an sr-only span in the summary content (the same approach used in goals/_color_picker.html.erb after beec50b4).


Scan coverage

/cc @gariasf

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions