From c5a902656d0aa455c934da847485b99df75d721b Mon Sep 17 00:00:00 2001 From: Jessica Lawshe <5312836+lawshe@users.noreply.github.com> Date: Tue, 23 Jan 2024 08:46:26 -0600 Subject: [PATCH] Merge pull request #16491 from overleaf/rd-plans-table [web] Accessibility - improve the navigation on the plans page GitOrigin-RevId: 8fccdfe5c60ad908f028608b79be74ca964fb65a --- .../app/views/subscriptions/plans/_mixins.pug | 35 ++++++++++++++++++- .../subscriptions/plans/_mixins_nudge.pug | 34 +++++++++++++++++- .../frontend/stylesheets/app/plans-v2.less | 27 ++++++-------- 3 files changed, 78 insertions(+), 18 deletions(-) diff --git a/services/web/app/views/subscriptions/plans/_mixins.pug b/services/web/app/views/subscriptions/plans/_mixins.pug index 073a521aed..0e472fd238 100644 --- a/services/web/app/views/subscriptions/plans/_mixins.pug +++ b/services/web/app/views/subscriptions/plans/_mixins.pug @@ -34,9 +34,39 @@ mixin plans_v2_table(period, config) } else { var thClass = '' } + thClass += ' plans-v2-table-column-header' + if (colspan > 1) { + var scopeValue = 'colgroup' + } + else { + var scopeValue = 'col' + } + case tableHeadKey + when 'individual_free' + - var ariaLabel = translate("free") + when 'individual_collaborator' + - var ariaLabel = translate("standard") + when 'individual_professional' + - var ariaLabel = translate("professional") + when 'group_collaborator' + - var ariaLabel = translate("group_standard") + when 'group_professional' + - var ariaLabel = translate("group_professional") + when 'group_organization' + - var ariaLabel = translate("organization") + when 'student_free' + - var ariaLabel = translate("free") + when 'student_student' + - var ariaLabel = translate("student") + when 'student_university' + - var ariaLabel = translate("university") + default + - var ariaLabel = undefined th( + aria-label=ariaLabel class=thClass colspan=colspan + scope=scopeValue ) .plans-v2-table-th if (discountHighlighted) @@ -93,12 +123,14 @@ mixin plans_v2_table(period, config) tr( class=(featureIndex === (featuresPerSection.items.length - 1) ? `plans-v2-table-row-last-row-per-section cols-${maxColumn}` : `cols-${maxColumn}`) ) - td( + th( + class="plans-v2-table-row-header" event-tracking="plans-page-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}` colspan=baseColspan + scope="row" ) .plans-v2-table-feature-name if feature.info @@ -118,6 +150,7 @@ mixin plans_v2_table(period, config) data-placement="top" ) #{translate("learn_more_lowercase")} span ) + span.sr-only #{translate(feature.info)} else | #{translate(feature.feature)} for plan, planIndex in Object.keys(feature.plans) diff --git a/services/web/app/views/subscriptions/plans/_mixins_nudge.pug b/services/web/app/views/subscriptions/plans/_mixins_nudge.pug index 702a21eade..ec28886af5 100644 --- a/services/web/app/views/subscriptions/plans/_mixins_nudge.pug +++ b/services/web/app/views/subscriptions/plans/_mixins_nudge.pug @@ -34,9 +34,39 @@ mixin plans_v2_table(period, config) } else { var thClass = '' } + thClass += ' plans-v2-table-column-header' + if (colspan > 1) { + var scopeValue = 'colgroup' + } + else { + var scopeValue = 'col' + } + case tableHeadKey + when 'individual_free' + - var ariaLabel = translate("free") + when 'individual_collaborator' + - var ariaLabel = translate("standard") + when 'individual_professional' + - var ariaLabel = translate("professional") + when 'group_collaborator' + - var ariaLabel = translate("group_standard") + when 'group_professional' + - var ariaLabel = translate("group_professional") + when 'group_organization' + - var ariaLabel = translate("organization") + when 'student_free' + - var ariaLabel = translate("free") + when 'student_student' + - var ariaLabel = translate("student") + when 'student_university' + - var ariaLabel = translate("university") + default + - var ariaLabel = undefined th( + aria-label=ariaLabel class=thClass colspan=colspan + scope=scopeValue ) .plans-v2-table-th if (discountHighlighted) @@ -93,12 +123,14 @@ mixin plans_v2_table(period, config) tr( class=(featureIndex === (featuresPerSection.items.length - 1) ? `plans-v2-table-row-last-row-per-section cols-${maxColumn}` : `cols-${maxColumn}`) ) - td( + th( + class="plans-v2-table-row-header" event-tracking="plans-page-table" event-tracking-trigger="hover" event-tracking-ga="subscription-funnel" event-tracking-label=`${feature.feature}` colspan=baseColspan + scope="row" ) .plans-v2-table-feature-name if feature.info diff --git a/services/web/frontend/stylesheets/app/plans-v2.less b/services/web/frontend/stylesheets/app/plans-v2.less index b7387b5e83..389c398db3 100644 --- a/services/web/frontend/stylesheets/app/plans-v2.less +++ b/services/web/frontend/stylesheets/app/plans-v2.less @@ -437,10 +437,6 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { } } } - - &:not(.plans-v2-table-divider) { - background-color: @white; - } } // only make corners have round borders if the column is not highlighted @@ -543,7 +539,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { // for remove-personal-plan split test default variant @media (max-width: @screen-xs-max) { tr.cols-4:not(.plans-v2-table-divider) { - td:not(:first-of-type), + td, th:not(:first-of-type) { // 25% is because table-individual have 4 real columns on mobile // it actually has 5 table columns, but on mobile version, the first column become row @@ -603,11 +599,15 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { // See https://stackoverflow.com/a/56913789 for more details height: 100%; + .plans-v2-table-row-header { + font-weight: 500; + } + tr { height: 100%; } - th, + .plans-v2-table-column-header, td { background-clip: padding-box; /* needed for firefox when there is bg color */ text-align: center; @@ -621,7 +621,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { } } - th { + .plans-v2-table-column-header { border-top: 0; font-family: @headings-font-family; font-size: @font-size-h2; @@ -645,11 +645,6 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { vertical-align: middle; height: 100%; - &:first-child { - border-left: 0; - text-align: left; - } - &:last-child:not(.plans-v2-table-green-highlighted):not(.plans-v2-table-divider-highlighted) { border-right: 0; } @@ -663,7 +658,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { // css hack for table border-radius on the first feature name &:nth-child(2) { - td:first-child { + .plans-v2-table-row-header:first-child { background-color: @ol-blue-gray-0; .plans-v2-table-feature-name { @@ -714,7 +709,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { @media (min-width: @screen-sm-min) { // highlight rows on hover - tr:not(.plans-v2-table-divider):hover td { + tr:not(.plans-v2-table-divider):hover { background-color: @table-hover-bg; .plans-v2-table-feature-name, @@ -739,7 +734,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { justify-content: space-around; } - th { + .plans-v2-table-column-header { font-size: 12px; } @@ -752,7 +747,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container { // the width: 100vw rule will enhance the flex-flow on the tr by ensuring the feature name (first column of each feature row) // will have the full width of viewport, // and making the first td appear like the it is in its own row (although it's technically still on the same tr as the other tds) - td:first-child { + .plans-v2-table-row-header { background: @gray-lightest; width: 100vw;