From 334d924bf31aa87b0830d0b9d6533e91a640c9ac Mon Sep 17 00:00:00 2001 From: Mike Patrick Date: Tue, 5 Sep 2023 11:56:43 +0100 Subject: [PATCH] `vertical_on_small_screen` Table component option Borrowing liberally from [Adam Fenwick's Responsive Accessible Table example](https://www.afenwick.com/blog/2021/responsive-accessible-table/). On tablet-sized screens and smaller, it switches the layout of the table into a vertical list of cards, which we believe is more usable for all. I've strayed from the example in the choice of screen size, because the specific case that I was using to test this (API Users index page) seems usable as a regular table on screens a fair bit smaller than "desktop". If that's not true for other tables in the app, we can easily change the hard-coded media queries or even supply the breakpoint as an argument to the component. I've essentially appended the new styling to the end of the existing component CSS because those existing styles apply more generally to all govuk-tables (i.e. they didn't specify the app-c-table class or prefix). I think it'll make more sense to merge the styles together when we're ready to merge our changes into the gem. --- app/assets/stylesheets/components/_table.scss | 71 +++++++++++++++++++ app/views/components/_table.html.erb | 12 +++- app/views/components/docs/table.yml | 29 ++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/components/_table.scss b/app/assets/stylesheets/components/_table.scss index bf04104172..95109b469a 100644 --- a/app/assets/stylesheets/components/_table.scss +++ b/app/assets/stylesheets/components/_table.scss @@ -5,6 +5,7 @@ $table-border-width: 1px; $table-border-colour: govuk-colour("mid-grey", $legacy: "grey-2"); $table-header-border-width: 2px; $table-header-background-colour: govuk-colour("light-grey", $legacy: "grey-3"); +$vertical-row-bottom-border-width: 3px; $sort-link-active-colour: govuk-colour("white"); $sort-link-arrow-size: 14px; $sort-link-arrow-size-small: 8px; @@ -133,3 +134,73 @@ $table-row-even-background-colour: govuk-colour("light-grey", $legacy: "grey-4") word-break: break-word; } } + +.app-c-table__vertical { + thead { + clip: rect(0 0 0 0); + -webkit-clip-path: inset(50%); + clip-path: inset(50%); + height: 1px; + overflow: hidden; + position: absolute; + width: 1px; + } + + tbody tr { + display: block; + } + + tbody tr td { + display: flex; + justify-content: space-between; + min-width: 1px; + text-align: right; + } + + @include govuk-media-query($until: tablet) { + tbody tr td { + padding-right: 0; + } + + tbody tr td:last-child { + border-bottom: 0 + } + + tbody tr { + border-bottom: $vertical-row-bottom-border-width solid $table-border-colour; + } + } + + .app-c-table__duplicate-heading { + font-weight: 700; + padding-right: 1em; + text-align: left; + word-break: initial; + } + + @include govuk-media-query($from: tablet) { + thead { + clip: auto; + -webkit-clip-path: none; + clip-path: none; + display: table-header-group; + height: auto; + overflow: auto; + position: relative; + width: auto; + } + + tbody tr { + display: table-row; + } + + tbody tr td { + display: table-cell; + text-align: left; + } + + .app-c-table__duplicate-heading { + display: none; + } + } +} diff --git a/app/views/components/_table.html.erb b/app/views/components/_table.html.erb index ba355b7fa9..e5f821eed3 100644 --- a/app/views/components/_table.html.erb +++ b/app/views/components/_table.html.erb @@ -6,10 +6,12 @@ caption_classes ||= nil sortable ||= false filterable ||= false + vertical_on_small_screen ||= false label ||= t("components.table.filter_label") table_id = "table-id-#{SecureRandom.hex(4)}" filter_count_id = "filter-count-id-#{SecureRandom.hex(4)}" + classes = "app-c-table__vertical" if vertical_on_small_screen %> <% @table = capture do %> @@ -17,7 +19,8 @@ sortable: sortable, filterable: filterable, caption_classes: caption_classes, - table_id: table_id + table_id: table_id, + classes: classes, }) do |t| %> <% if head.any? %> @@ -42,6 +45,13 @@ scope: "row", format: cell[:format] } %> + <% elsif vertical_on_small_screen && head.any? %> + <%= t.cell nil, { format: cell[:format] } do %> + + <%= cell[:text] %> + <% end %> <% else %> <%= t.cell cell[:text], { format: cell[:format] diff --git a/app/views/components/docs/table.yml b/app/views/components/docs/table.yml index 9c06f5f896..19e87012a5 100644 --- a/app/views/components/docs/table.yml +++ b/app/views/components/docs/table.yml @@ -169,3 +169,32 @@ examples: format: numeric - text: £125 format: numeric + vertical_layout_on_small_screens: + description: This option only kicks-in on tablet-sized screens and smaller. It switches the layout of the table into a vertical list of cards. In this new layout, the table's main header is hidden but a copy of the relevant heading text is embedded into each table cell. + data: + vertical_on_small_screen: true + head: + - text: Month you apply + - text: Rate for bicycles + format: numeric + - text: Rate for vehicles + format: numeric + rows: + - + - text: January + - text: £85 + format: numeric + - text: £95 + format: numeric + - + - text: February + - text: £75 + format: numeric + - text: £55 + format: numeric + - + - text: March + - text: £165 + format: numeric + - text: £125 + format: numeric