diff --git a/etaf-ui.el b/etaf-ui.el index 333ba16..03397f6 100644 --- a/etaf-ui.el +++ b/etaf-ui.el @@ -106,6 +106,24 @@ TAB-INDEX, and ARIA-LABEL provide Host identity and presentation." ((listp row) (alist-get key row)) (t nil))) +(defun etaf-ui--grid-display-value (row column) + "Return one single-line display value for ROW and COLUMN. + +DataGrid columns are tabular tracks, not prose paragraphs. Keep each cell on +one visual line and use an ellipsis when a fixed character-width descriptor is +too small; the original ROW remains intact for selection and callbacks." + (let* ((value (format "%s" + (or (etaf-ui--grid-cell-value + row (etaf-ui--column-value column :key)) ""))) + (width (etaf-ui--column-value column :width))) + (if (and (integerp width) (> width 1) + (> (string-width value) width)) + ;; Leave one character of the declared track for inter-column air; + ;; Ebox's left justification fills that remainder without changing + ;; the stable column geometry. + (truncate-string-to-width value (1- width) 0 nil "…") + value))) + (defun etaf-ui--grid-header-cell (column) "Return one header View for COLUMN." (etaf-view @@ -124,11 +142,9 @@ TAB-INDEX, and ARIA-LABEL provide Host identity and presentation." (defun etaf-ui--grid-cell (row column) "Return one data cell View for ROW and COLUMN." - (let ((key (etaf-ui--column-value column :key))) - (etaf-view - (text :width (etaf-ui--column-value column :width) - (expr :value - (format "%s" (or (etaf-ui--grid-cell-value row key) ""))))))) + (etaf-view + (text :width (etaf-ui--column-value column :width) + (expr :value (etaf-ui--grid-display-value row column))))) (defun etaf-ui--grid-cells (row columns) "Return data cell Views for ROW and COLUMNS." diff --git a/tests/etaf-ui-tests.el b/tests/etaf-ui-tests.el index 6a79f39..fa5e696 100644 --- a/tests/etaf-ui-tests.el +++ b/tests/etaf-ui-tests.el @@ -451,6 +451,31 @@ (when-let ((buffer (get-buffer buffer-name))) (kill-buffer buffer))))) +(ert-deftest etaf-ui-data-grid-keeps-long-cells-on-one-line () + "Long tabular values use an ellipsis instead of increasing row height." + (let* ((source (etaf-data-memory-source + '((:id 1 :title "The Cathedral and the Bazaar")) + :id-key :id)) + (controller (etaf-data-controller source :page-size 10 :auto-load t)) + (buffer-name " *etaf-ui-grid-truncation-test*")) + (unwind-protect + (progn + (etaf-mount + buffer-name + (etaf-view + (data-grid + :controller controller + :columns '((:key :title :label "Title" :width 22)) + :row-key (lambda (row) (plist-get row :id))))) + (let ((text (etaf-ui-test--text buffer-name))) + (should (string-match-p "The Cathedral and th…" text)) + (should-not (string-match-p "The Cathedral and the Bazaar" text)))) + (when-let ((runtime (etaf-runtime-for-buffer buffer-name))) + (etaf-unmount runtime)) + (etaf-data-stop controller) + (when-let ((buffer (get-buffer buffer-name))) + (kill-buffer buffer))))) + (ert-deftest etaf-ui-data-grid-noninteractive-rows-have-no-focus-contract () "Rows without ON-ROW-PRESS have no role, ref callback, or tab stop." (let* ((source (etaf-data-memory-source '((:id 1 :name "Ada"))