Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions app/assets/javascripts/wigu/table_crisscross.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Crisscross highlighting for ActiveAdmin index tables. Clicking a cell marks
// its whole row and column with class "selected", which the stylesheet paints
// with var(--aa-selected) — so the clicked cell sits at the centre of a
// highlighted cross, making it easy to trace a value to its row and column in a
// wide table.
//
// Uses jQuery, which ActiveAdmin loads before this file (its own
// checkbox-toggler is jQuery too); the rest of the theme JS is dependency-free,
// but this behaviour lives entirely in AA's jQuery-driven index table.
//
// AA's table-checkbox-toggler selects the row when a cell is clicked; we undo
// that (re-click the checkbox) so crisscross highlighting never leaves rows
// ticked for batch actions.
$(document).ready(function () {
var marker = 'selected';

// "Select all" clears every row marker left by AA's toggler.
$('table.index_table .toggle_all').click(function () {
$(this).closest('table').find('tr.' + marker).removeClass(marker);
});

// Clicking the row checkbox itself must not bubble into the cell handler.
$('table.index_table').find(':checkbox').click(function (e) {
e.stopPropagation();
$(this).closest('tr.' + marker).removeClass(marker);
});

$('table.index_table').on('click', 'td', function (e) {
var tdIndex = e.currentTarget.cellIndex,
$cell = $(e.currentTarget),
$table = $cell.closest('table'),
$row = $cell.closest('tr'),
$columnTds = $table.find('td:nth-child(' + (tdIndex + 1) + ')'),
$rowTds = $row.find('td');

// AA ticks the row checkbox on a cell click; click it again to revert.
$row.find(':checkbox').click();

if (!$cell.hasClass('col-selectable')) {
$table.find('td.' + marker).removeClass(marker);
$table.find('td.selected-cell').removeClass('selected-cell');
$columnTds.addClass(marker);
$rowTds.addClass(marker);
// Mark the clicked cell itself so the stylesheet can set it apart as the
// centre of the cross.
$cell.addClass('selected-cell');
}
});
});
15 changes: 13 additions & 2 deletions app/assets/stylesheets/wigu/active_admin_theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1774,11 +1774,22 @@ input[type='radio'] {
// Selected cells: the zebra and hover rules above outrank ActiveAdmin's own
// `tr.selected td` / `td.selected`, so without this a ticked row (batch
// actions) or a click-highlighted row + column (crisscross) looks unselected.
// The :hover variants keep the selection visible under the pointer.
// The `tr >` in the td.selected selector is load-bearing: the even-stripe
// rule is `...tbody tr:nth-child(even) > td` (specificity 0,0,2,4); a plain
// `tbody td.selected` is only (0,0,2,3) and loses on even rows, breaking the
// cross every other row. Matching the `tr >` ties the specificity, so source
// order wins. The :hover variants keep the selection visible under the pointer.
table.index_table tbody tr.selected > td,
table.index_table tbody tr.selected:hover > td,
table.index_table tbody td.selected,
table.index_table tbody tr > td.selected,
table.index_table tbody tr:hover > td.selected { background: var(--aa-selected); }
// The clicked cell sits at the centre of the cross; an accent outline marks
// it apart from the row/column tint without a competing fill (outset inward
// so it adds no layout shift).
table.index_table tbody tr > td.selected-cell {
outline: 2px solid var(--aa-accent);
outline-offset: -2px;
}
// Plain content tables (e.g. the CDR show "Attempts" table) are striped by the
// base CSS with light fills; map the odd/even rows onto the dark surfaces too.
table tbody tr.odd > td, table tbody tr.odd > th { background-color: var(--aa-surface); }
Expand Down
Binary file added img/crisscross-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/crisscross-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions test/crisscross_screenshot.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Regenerates img/crisscross-light.png / img/crisscross-dark.png — the crisscross
# cell highlighting (wigu/table_crisscross.js) in both palettes. Clicks a middle
# cell so the screenshot shows the highlighted row + column crossing at it, then
# crops to the demo panel.
require_relative "capybara_boot"
require "capybara/dsl"

include Capybara::DSL

visit "/admin/table"
# Click a cell away from the edges so the cross is clearly centred (row 3, Email).
find("table.index_table tbody tr:nth-child(3) td:nth-child(3)").click
page.driver.resize_window_to(page.driver.window_handles.first, 1120, 640)

{ "light" => "crisscross-light.png", "dark" => "crisscross-dark.png" }.each do |theme, file|
page.execute_script(%(document.documentElement.setAttribute('data-theme', '#{theme}')))
sleep 0.3
out = File.expand_path("../img/#{file}", __dir__)
page.driver.browser.screenshot(path: out, selector: ".panel")
puts "wrote #{out} (#{File.size(out)} bytes)"
end

Capybara.reset_sessions!
29 changes: 29 additions & 0 deletions test/dummy/app/admin/table.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Demo page with a plain index table so the crisscross highlighting (wigu/
# table_crisscross.js) can be exercised and screenshotted: clicking a cell marks
# its whole row and column with .selected, which the theme paints.
ActiveAdmin.register_page "Table" do
menu priority: 3

ROWS = [
%w[101 Ada\ Lovelace ada@example.com UK Active],
%w[102 Alan\ Turing alan@example.com UK Active],
%w[103 Grace\ Hopper grace@example.com US Closed],
%w[104 Katherine\ Johnson katherine@example.com US Active],
%w[105 Edsger\ Dijkstra edsger@example.com NL Closed],
%w[106 Donald\ Knuth donald@example.com US Active]
].freeze

content do
panel "Crisscross highlighting (click a cell)" do
head = "<thead><tr><th>ID</th><th>Name</th><th>Email</th>" \
"<th>Country</th><th>Status</th></tr></thead>"
body = ROWS.map do |r|
"<tr>" + r.map { |c| "<td>#{ERB::Util.html_escape(c)}</td>" }.join + "</tr>"
end.join
text_node(
(%(<table class="index_table">) + head + "<tbody>" + body + "</tbody></table>")
.html_safe
)
end
end
end
1 change: 1 addition & 0 deletions test/dummy/app/assets/javascripts/active_admin.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//= require active_admin/base
//= require wigu/server_clock
//= require wigu/theme_toggle
//= require wigu/table_crisscross
Loading