From 33c625ad82fd94ee122b9f4d671a2add8d478c4c Mon Sep 17 00:00:00 2001 From: Kinneyzhang Date: Sat, 22 Aug 2026 10:19:12 +0800 Subject: [PATCH] Make minmax grid tracks responsive --- ebox-grid.el | 26 +++++++++++++++++--------- tests/ebox-grid-tests.el | 13 +++++++++++++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/ebox-grid.el b/ebox-grid.el index 3a87641..9a8d36e 100644 --- a/ebox-grid.el +++ b/ebox-grid.el @@ -368,6 +368,17 @@ Supported properties are `:grid-column', `:grid-row', ('minmax (ebox-grid--track-max (plist-get track :max))) (_ nil))) +(defun ebox-grid--track-flex-factor (track) + "Return TRACK's flexible maximum factor, or zero when it is fixed. + +`minmax' tracks commonly use a zero minimum with a fractional maximum for +responsive layouts. Treat that maximum as a real flexible track instead of +letting the grid fall back to each child's intrinsic width." + (pcase (plist-get track :kind) + ('fr (plist-get track :factor)) + ('minmax (ebox-grid--track-flex-factor (plist-get track :max))) + (_ 0))) + (defun ebox-grid--clamp-track-size (track size) "Clamp SIZE to TRACK's fixed maximum when one exists." (if-let ((maximum (ebox-grid--track-max track))) @@ -391,21 +402,18 @@ Supported properties are `:grid-column', `:grid-row', track axis entries rendered (if (eq axis 'columns) :column :row) index)))) - (fr-total (apply #'+ - (mapcar (lambda (track) - (if (eq (plist-get track :kind) 'fr) - (plist-get track :factor) 0)) - tracks))) + (fr-total (apply #'+ (mapcar #'ebox-grid--track-flex-factor tracks))) (used (+ (ebox-grid--sum sizes) (* gap (max 0 (1- count)))))) (when (and available (> fr-total 0)) (let ((remaining (max 0 (- available used)))) (cl-loop for track in tracks for index from 0 - when (eq (plist-get track :kind) 'fr) + for factor = (ebox-grid--track-flex-factor track) + when (> factor 0) do (setf (nth index sizes) - (floor (* remaining - (/ (float (plist-get track :factor)) - fr-total))))))) + (max (nth index sizes) + (floor (* remaining + (/ (float factor) fr-total)))))))) sizes)) (defun ebox-grid--distribute (amount count) diff --git a/tests/ebox-grid-tests.el b/tests/ebox-grid-tests.el index b1ef77f..958fb03 100644 --- a/tests/ebox-grid-tests.el +++ b/tests/ebox-grid-tests.el @@ -37,6 +37,19 @@ (should (= (length lines) 1)) (should (= (ebox--string-pixel-width (car lines)) 120)))) +(ert-deftest ebox-grid-minmax-fractional-columns-fill-and-shrink () + "Zero-minimum fractional maxima should remain responsive to width." + (dolist (width '(120 60)) + (let* ((node (ebox-grid + :width (list width) + :grid-template-columns + '((minmax (0) (fr 1)) (minmax (0) (fr 2))) + (ebox-create :content "A" :width 'stretch) + (ebox-create :content "B" :width 'stretch))) + (lines (ebox-string-lines (ebox-render node)))) + (should (= (ebox--string-max-pixel-width + (car lines)) width))))) + (ert-deftest ebox-grid-stretch-children-fill-fractional-tracks () "Stretch-width children must reflow to their assigned fractional tracks." (let* ((left (ebox-create :content "left" :width 'stretch))