Kaynağa Gözat

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
M Fahru 2 yıl önce
ebeveyn
işleme
920e86e4d0

+ 4 - 3
services/web/app/src/Features/Subscription/plansConfig.js

@@ -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,

+ 11 - 20
services/web/app/views/subscriptions/plans/_mixins.pug

@@ -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 = ''

+ 0 - 0
services/web/frontend/stylesheets/app/plans-ol.less → services/web/frontend/stylesheets/app/plans/plans-ol.less


+ 51 - 105
services/web/frontend/stylesheets/app/plans-v2.less → services/web/frontend/stylesheets/app/plans/plans-v2.less

@@ -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 {

+ 0 - 0
services/web/frontend/stylesheets/app/plans.less → services/web/frontend/stylesheets/app/plans/plans.less


+ 3 - 3
services/web/frontend/stylesheets/main-style.less

@@ -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