Browse Source

fix(label-picker): allow spool list to shrink so all 4 templates and Cancel stay visible (issue #1230)

  The Print Labels modal used a flex column with overflow-hidden on the
  outer container, the spool list as the flex-1 shrinkable child, and the
  templates + footer as fixed siblings below it. The spool list had
  min-h-[160px], which combined with the implicit min-height: auto on
  flex items meant it could not yield space when the modal was tight —
  templates and the Cancel button overflowed the modal's max-h-[90vh] and
  got clipped. Reproducible on Windows 11 + Brave at 1080p with browser
  chrome / DPI scaling reducing the effective viewport.

  Switching to min-h-0 both removes the explicit floor and overrides
  min-height: auto so flex shrinking actually works; the spool list now
  yields height to keep all four templates and the Cancel button visible
  on constrained viewports. Larger viewports behave identically since
  flex-1 still grows to fill.

  Adds a regression test that asserts all four template names + the
  Cancel button render in the DOM and pins the structural fix by
  checking the spool list scroller has min-h-0 with no min-h-[…] literal.
maziggy 3 weeks ago
parent
commit
61314cf20b

File diff suppressed because it is too large
+ 0 - 0
CHANGELOG.md


+ 33 - 0
frontend/src/__tests__/components/LabelTemplatePickerModal.test.tsx

@@ -274,4 +274,37 @@ describe('LabelTemplatePickerModal', () => {
     fireEvent.change(screen.getByPlaceholderText(/Search/i), { target: { value: 'zzz-no-match' } });
     expect(screen.getByText(/No spools match/i)).toBeInTheDocument();
   });
+
+  it('lets the spool list shrink (min-h-0) so all 4 templates and Cancel stay visible on short viewports (#1230)', () => {
+    // Regression for #1230: on viewports where 90vh is tight (Windows 11
+    // browser-chrome or DPI scaling), an explicit min-h on the spool list
+    // pinned it taller than the modal could give back to templates + footer,
+    // and `overflow-hidden` on the outer modal clipped the 4th template
+    // (Avery 5160) and the Cancel button. The fix is `min-h-0` so the
+    // flex-1 spool list can yield space when needed.
+    const { container } = render(
+      <LabelTemplatePickerModal
+        isOpen={true}
+        onClose={vi.fn()}
+        availableSpools={SPOOLS}
+        initialSelectedIds={[]}
+        spoolmanMode={false}
+      />,
+    );
+
+    // All 4 templates must be in the DOM, including the last one.
+    expect(screen.getByText(/AMS holder/i)).toBeInTheDocument();
+    expect(screen.getByText(/Box label/i)).toBeInTheDocument();
+    expect(screen.getByText(/Avery L7160/i)).toBeInTheDocument();
+    expect(screen.getByText(/Avery 5160/i)).toBeInTheDocument();
+    expect(screen.getByRole('button', { name: /Cancel/i })).toBeInTheDocument();
+
+    // Structural guard against the regression: the scrollable spool list
+    // must have `min-h-0` so flex shrinking actually works, and must NOT
+    // pin a fixed minimum height that prevents it.
+    const spoolListScroller = container.querySelector('div.flex-1.overflow-y-auto');
+    expect(spoolListScroller).not.toBeNull();
+    expect(spoolListScroller!.className).toContain('min-h-0');
+    expect(spoolListScroller!.className).not.toMatch(/min-h-\[\d/);
+  });
 });

+ 1 - 1
frontend/src/components/LabelTemplatePickerModal.tsx

@@ -308,7 +308,7 @@ export function LabelTemplatePickerModal({
         </div>
 
         {/* Spool list */}
-        <div className="flex-1 overflow-y-auto px-2 pb-2 min-h-[160px]">
+        <div className="flex-1 overflow-y-auto px-2 pb-2 min-h-0">
           {visibleSpools.length === 0 ? (
             <div className="text-center text-sm text-bambu-gray py-6">
               {sortedSpools.length === 0

Some files were not shown because too many files changed in this diff