Quellcode durchsuchen

Improve block preview layout for responsiveness and reduced shifting

Sage Abdullah vor 2 Monaten
Ursprung
Commit
db87deb0c8

+ 37 - 12
client/src/components/ComboBox/ComboBox.scss

@@ -2,12 +2,21 @@
 // With the scrolling and show/hide of the field, correct spacing is critical.
 $spacing: theme('spacing.[2.5]');
 $spacing-sm: theme('spacing.5');
+$width: min(1000px, 75vw);
 
 .w-combobox-container {
   @include dark-theme() {
     background-color: theme('colors.surface-tooltip');
   }
 
+  background: theme('colors.surface-page');
+  color: theme('colors.text-context');
+  border-radius: theme('borderRadius.DEFAULT');
+  box-shadow: theme('boxShadow.md');
+  outline: 10px solid transparent;
+
+  // Use a single column grid on smaller screens,
+  // and two columns on larger screens.
   display: grid;
   grid-template-columns: 1fr;
   @include media-breakpoint-up(md) {
@@ -17,20 +26,36 @@ $spacing-sm: theme('spacing.5');
     grid-template-columns: min(512px, 80vw) 1fr;
   }
 
+  // Case 1: base case
+  // Use max-content width to minimize shifting due to content wrapping,
+  // while also ensuring it's not wider than 75% of the viewport.
   width: max-content;
-  max-width: min(1024px, 75vw);
-  max-height: min(768px, 75vh);
-  background: theme('colors.surface-page');
-  color: theme('colors.text-context');
-  border-radius: theme('borderRadius.DEFAULT');
-  box-shadow: theme('boxShadow.md');
-  outline: 10px solid transparent;
-
-  // Only apply min-height if at least one block has a preview.
-  // We don't target `.w-combobox-preview` as the preview component only renders
-  // when a preview is present.
+  max-width: 75vw;
+
+  // Case 2: there's a previewable block, but the preview may or may not be active
+  // On smaller screens, the preview will be shown below. We don't want the
+  // combobox to change width when the preview is shown or hidden (e.g. due to
+  // a long description), so set a fixed width. It's OK that this will take up
+  // more than the necessary width for the combobox, as we know it's not going
+  // to be wider than 75% of the small screen anyway.
   &:has(.w-combobox__option-preview) {
-    min-height: min(320px, 70vh);
+    width: $width;
+
+    @include media-breakpoint-up(md) {
+      // On medium-up screens, the preview will be shown to the right. Revert
+      // the width back to max-content so it doesn't take up the whole `$width`
+      // when the preview is not active.
+      width: max-content;
+    }
+  }
+
+  // Case 3: the preview is currently active
+  &:has(.w-combobox-preview) {
+    @include media-breakpoint-up(md) {
+      // On larger screens, use the fixed `$width` so the width doesn't change
+      // for different blocks, which may have different description lengths.
+      width: $width;
+    }
   }
 }
 

+ 11 - 5
client/src/components/ComboBoxPreview/ComboBoxPreview.scss

@@ -1,9 +1,10 @@
 .w-combobox-preview {
   padding: theme('spacing.5');
-  display: grid;
-  grid-template-rows: 6fr 4fr;
+  display: flex;
+  flex-direction: column;
   gap: theme('spacing.5');
-  min-height: 0;
+  // Set a min-height to ensure it's big enough to be useful
+  min-height: 400px;
   background-color: theme('colors.surface-header');
   border-block-start: 1px solid theme('colors.border-furniture');
   border-end-end-radius: inherit;
@@ -17,8 +18,10 @@
 }
 
 .w-combobox-preview__iframe {
+  // Take up remaining space
   width: 100%;
   height: 100%;
+
   border: 1px solid theme('colors.border-furniture');
   border-radius: theme('borderRadius.sm');
 
@@ -35,12 +38,14 @@
   overflow: hidden;
   display: flex;
   flex-direction: column;
+  // Use 65:35 ratio between the iframe and the details, but allow the details
+  // to grow to a minimum of 100px in case the container is very small
+  // (i.e. when there are only a few blocks)
+  min-height: max(35%, 100px);
 }
 
 .w-combobox-preview__label {
   @apply w-label-1;
-  max-height: 25%;
-  overflow: auto;
 }
 
 .w-combobox-preview__description {
@@ -48,4 +53,5 @@
   margin-top: theme('spacing.3');
   margin-bottom: 0;
   overflow: auto;
+  min-height: 0;
 }