Merge pull request #17303 from overleaf/mf-fix-plans-page-mobile

[web] Fix plans page table styling on both desktop and mobile

GitOrigin-RevId: 252bbaf7245751b1cfe07286a0fe19069219bb5b
This commit is contained in:
M Fahru 2024-03-01 06:11:25 -07:00 committed by Copybot
parent 95105d9f96
commit 920e86e4d0
6 changed files with 69 additions and 131 deletions

View file

@ -20,6 +20,7 @@ const config = {
additionalEventSegmentation: {},
},
group: {
maxColumn: 3,
tableHead: {
group_collaborator: {},
group_professional: {},
@ -36,15 +37,15 @@ const config = {
additionalEventSegmentation: {},
},
student: {
baseColspan: 2,
baseColspan: 1,
maxColumn: 3,
tableHead: {
student_free: {
colspan: 3,
colspan: 1,
},
student_student: {
showExtraContent: false,
colspan: 3,
colspan: 1,
},
},
features: plansFeatures.student,

View file

@ -13,21 +13,18 @@ mixin gen_localized_price_for_plan_view(plan, view)
mixin plans_v2_table(period, config)
- var baseColspan = config.baseColspan || 1
- var maxColumn = config.maxColumn || 4
- var discountedColumn = config.discountedColumn || {}
tr(class=`cols-${maxColumn}`)
- var tableHeadKeys = Object.keys(config.tableHead)
tr(class=`plans-v2-table-cols-${tableHeadKeys.length}`)
th(colspan=baseColspan)
- for (var i = 0; i < maxColumn; i++)
- var tableHeadKey = Object.keys(config.tableHead)[i]
- var tableHeadKey = tableHeadKeys[i]
- var tableHeadOptions = Object.values(config.tableHead)[i] || {}
- var colspan = tableHeadOptions.colspan || baseColspan
- var highlighted = i === config.highlightedColumn.index
- var discountHighlighted = i === discountedColumn.index
- var eventTrackingKey = config.eventTrackingKey
- var additionalEventSegmentation = config.additionalEventSegmentation || {}
-
if (discountHighlighted) {
var thClass = 'plans-v2-table-discount-highlighted'
} else if (highlighted) {
if (highlighted) {
var thClass = 'plans-v2-table-green-highlighted'
} else if (i === config.highlightedColumn.index - 1) {
var thClass = 'plans-v2-table-cell-before-green-highlighted-column'
@ -69,8 +66,6 @@ mixin plans_v2_table(period, config)
scope=scopeValue
)
.plans-v2-table-th
if (discountHighlighted)
p.plans-v2-table-discount-highlighted-text #{translate(config.discountedColumn.text[period]).toUpperCase()}
if (highlighted)
p.plans-v2-table-green-highlighted-text #{translate(config.highlightedColumn.text[period]).toUpperCase()}
case tableHeadKey
@ -121,7 +116,7 @@ mixin plans_v2_table(period, config)
span.sr-only #{translate(featuresPerSection.dividerInfo)}
for feature, featureIndex in featuresPerSection.items
tr(
class=(featureIndex === (featuresPerSection.items.length - 1) ? `plans-v2-table-row-last-row-per-section cols-${maxColumn}` : `cols-${maxColumn}`)
class=(featureIndex === (featuresPerSection.items.length - 1) ? `plans-v2-table-row-last-row-per-section plans-v2-table-cols-${tableHeadKeys.length}` : `plans-v2-table-cols-${tableHeadKeys.length}`)
)
th(
class="plans-v2-table-row-header"
@ -157,9 +152,7 @@ mixin plans_v2_table(period, config)
- var tableHeadOptions = Object.values(config.tableHead)[planIndex] || {}
- var colspan = tableHeadOptions.colspan || baseColspan
-
if (planIndex === discountedColumn.index) {
var tdClass = 'plans-v2-table-discount-highlighted'
} else if (planIndex === config.highlightedColumn.index) {
if (planIndex === config.highlightedColumn.index) {
var tdClass = 'plans-v2-table-green-highlighted'
} else if (planIndex === config.highlightedColumn.index - 1) {
var tdClass = 'plans-v2-table-cell-before-green-highlighted-column'
@ -417,12 +410,12 @@ mixin group_plans_license_picker()
span )
span.sr-only #{translate("apply_educational_discount_info")}
mixin btn_buy_individual(highlighted, discountHighlighted, eventTrackingKey, subscriptionPlan, period)
mixin btn_buy_individual(highlighted, eventTrackingKey, subscriptionPlan, period)
a.btn.plans-v2-table-btn-buy(
data-ol-start-new-subscription=subscriptionPlan
data-ol-event-tracking-key=eventTrackingKey
data-ol-item-view=period
class=(discountHighlighted ? 'btn-dark-blue' : (highlighted ? 'btn-primary' : 'btn-default'))
class=(highlighted ? 'btn-primary' : 'btn-default')
)
if (period === 'monthly')
span #{translate("try_for_free")}
@ -443,12 +436,12 @@ mixin btn_buy_individual_free()
)
mixin btn_buy_individual_collaborator(highlighted, eventTrackingKey, additionalEventSegmentation, period)
+btn_buy_individual(highlighted, false, eventTrackingKey, 'collaborator', period)
+btn_buy_individual(highlighted, eventTrackingKey, 'collaborator', period)
if (period === 'monthly')
+additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'collaborator', period)
mixin btn_buy_individual_professional(highlighted, eventTrackingKey, additionalEventSegmentation, period)
+btn_buy_individual(highlighted, false, eventTrackingKey, 'professional', period)
+btn_buy_individual(highlighted, eventTrackingKey, 'professional', period)
if (period === 'monthly')
+additional_link_buy(eventTrackingKey, additionalEventSegmentation, 'professional', period)
@ -565,9 +558,7 @@ mixin plans_v2_table_sticky_header(withSwitch, config)
- var tableHeadKey = tableHeadKeys[i]
- var translateKey = tableHeadKey.split('_')[1]
-
if (config.discountedColumn?.index === i) {
var elClass = 'plans-v2-table-sticky-header-item-discount-highlighted'
} else if (config.highlightedColumn.index === i) {
if (config.highlightedColumn.index === i) {
var elClass = 'plans-v2-table-sticky-header-item-green-highlighted'
} else {
var elClass = ''

View file

@ -7,9 +7,7 @@
@plans-v2-highlighted-text-height-mobile: 41px;
@plans-v2-learn-more-link-color: hsl(206, 100%, 52%);
@plans-v2-top-switch-group-width-mobile: 46%;
@plans-v2-discount-highlighted-text-z-index: 2;
@plans-v2-table-border-radius: 20px;
@plans-v2-dark-blue: #2857a1;
@plans-v2-table-td-mobile-min-height: 34px;
.plans {
@ -18,11 +16,6 @@
display: none;
}
}
.btn-dark-blue {
background-color: @plans-v2-dark-blue;
color: @white;
}
}
.plans-v2-top-switch ul.plans-v2-nav {
@ -404,7 +397,6 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
}
}
.plans-v2-table-group,
.plans-v2-table-student {
tr {
// "hide" the last column on desktop by making the background-color as the default background color
@ -459,7 +451,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
}
@media (max-width: @screen-md-max) {
tr {
tr:first-of-type {
th:last-of-type {
// Last column is only a UI placeholder for desktop view.
// We need to hide it for mobile to have the full table fully visible on mobile
@ -468,21 +460,6 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
}
}
}
@media (max-width: @screen-xs-max) {
tr {
&:not(.plans-v2-table-divider) {
td:not(:first-of-type),
th:not(:first-of-type) {
// 33.33% is because table-group & table-student have 3 real column on mobile.
// It actually has 5 table column, but on mobile version,
// the first column become row and the last column is hidden since it is just a UI placeholder.
// We need to force 33.33% width to make each of 3 columns have an equal width of 1/3 screen width.
width: 33.33%;
}
}
}
}
}
.plans-v2-table-individual {
@ -535,29 +512,6 @@ 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,
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
// we need to force 25% width to make each of 4 columns have an equal width of 1/4 screen width
width: 25%;
}
}
// for remove-personal-plan split test personal-off variant
tr.cols-3:not(.plans-v2-table-divider) {
td:not(:first-of-type),
th:not(:first-of-type) {
// 33% is because table-individual have 3 real columns on mobile
// it actually has 4 table columns, but on mobile version, the first column become row
// we need to force 33% width to make each of 3 columns have an equal width of 1/3 screen width
width: calc(100% / 3);
}
}
}
}
.plans-v2-table-group {
@ -580,6 +534,30 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
font-size: @font-size-small;
}
}
tr {
// top right border radius on desktop only
&:first-of-type {
th:last-child > .plans-v2-table-th {
border-top-right-radius: @plans-v2-table-border-radius;
@media (max-width: @screen-xs-max) {
border-top-right-radius: 0;
}
}
}
// bottom right border radius on desktop only
&:last-of-type {
td:last-child > .plans-v2-table-cell {
border-bottom-right-radius: @plans-v2-table-border-radius;
@media (max-width: @screen-xs-max) {
border-bottom-right-radius: 0;
}
}
}
}
}
.plans-v2-table {
@ -612,7 +590,7 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
background-clip: padding-box; /* needed for firefox when there is bg color */
text-align: center;
&:not(.plans-v2-table-cell-before-green-highlighted-column):not(.plans-v2-table-green-highlighted):not(.plans-v2-table-divider-highlighted):not(.plans-v2-table-discount-highlighted) {
&:not(.plans-v2-table-cell-before-green-highlighted-column):not(.plans-v2-table-green-highlighted):not(.plans-v2-table-divider-highlighted) {
border-right: 1px solid @ol-blue-gray-0;
@media (max-width: @screen-xs-max) {
@ -693,14 +671,6 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
}
}
}
&:last-child td.plans-v2-table-discount-highlighted {
border-bottom: 2px solid @plans-v2-dark-blue;
@media (max-width: @screen-xs-max) {
border-bottom: unset;
}
}
}
.fa-check {
@ -734,6 +704,30 @@ span.plans-v2-license-picker-educational-discount-learn-more-container {
justify-content: space-around;
}
// The forced width below (plans-v2-table-cols-n) is to ensure the table columns have an equal width
// because on mobile, the first column (empty cell on first `tr` and feature name on the rest of `tr`) will be shown as its own row
// and the rest of the `tr` will incorporate a full width of the viewport
tr.plans-v2-table-cols-4:not(.plans-v2-table-divider) {
td,
th:not(:first-of-type) {
width: 25%;
}
}
tr.plans-v2-table-cols-3:not(.plans-v2-table-divider) {
td,
th:not(:first-of-type) {
width: calc(100% / 3);
}
}
tr.plans-v2-table-cols-2:not(.plans-v2-table-divider) {
td,
th:not(:first-of-type) {
width: 50%;
}
}
.plans-v2-table-column-header {
font-size: 12px;
}
@ -1062,7 +1056,7 @@ tr.plans-v2-table-divider {
}
}
.plans-v2-table-divider-highlighted {
.plans-v2-table-divider-highlighted > div {
border-right: none;
}
}
@ -1114,50 +1108,6 @@ p.plans-v2-table-green-highlighted-text {
}
}
.plans-v2-table-discount-highlighted {
border-left: 2px solid @plans-v2-dark-blue;
border-right: 2px solid @plans-v2-dark-blue;
@media (max-width: @screen-xs-max) {
border-left: unset;
border-right: unset;
}
}
p.plans-v2-table-discount-highlighted-text {
border: 2px solid @plans-v2-dark-blue;
position: absolute;
top: -1 * @plans-v2-highlighted-text-height-desktop;
left: -2px;
display: flex;
justify-content: center;
align-items: center;
// 4px because border width is 2px each side (left and right)
width: calc(100% + 4px);
font-family: @font-family-sans-serif;
font-size: @font-size-small;
line-height: 19px;
font-weight: 700;
background-color: @plans-v2-dark-blue;
border-radius: @plans-v2-table-border-radius @plans-v2-table-border-radius 0 0;
color: @white;
height: @plans-v2-highlighted-text-height-desktop;
margin: 0;
z-index: @plans-v2-discount-highlighted-text-z-index;
@media (max-width: @screen-sm-max) {
top: -1 * @plans-v2-highlighted-text-height-mobile;
height: @plans-v2-highlighted-text-height-mobile;
}
@media (max-width: @screen-xs-max) {
padding-left: 5px;
padding-right: 5px;
font-size: @font-size-extra-small;
line-height: 15px;
}
}
.plans-v2-table-sticky-header-container {
@media (max-width: @screen-xs-max) {
// `height: 60%` is just an arbitrary percentage
@ -1224,10 +1174,6 @@ p.plans-v2-table-discount-highlighted-text {
color: @ol-green;
}
.plans-v2-table-sticky-header-item-discount-highlighted span {
color: @plans-v2-dark-blue;
}
.plans-v2-faq {
// need for specificity to override default a color
p > a {

View file

@ -103,8 +103,9 @@
@import 'app/project-list-react.less';
@import 'app/editor.less';
@import 'app/homepage.less';
@import 'app/plans.less';
@import 'app/plans-v2.less';
@import 'app/plans/plans.less';
@import 'app/plans/plans-ol.less';
@import 'app/plans/plans-v2.less';
@import 'app/recurly.less';
@import 'app/bonus.less';
@import 'app/register.less';
@ -139,7 +140,6 @@
@import 'app/blog-posts.less';
@import 'app/cms-page.less';
@import 'app/content_page.less';
@import 'app/plans-ol.less';
@import 'app/portals.less';
// module styles