perf: simplify retained data grid rows

This commit is contained in:
Kinneyzhang 2026-08-31 16:06:09 +08:00
parent a4181d0db1
commit 4d0d63bbb3
3 changed files with 30 additions and 42 deletions

View File

@ -178,7 +178,7 @@ candidate values; THEME is the resolved table-paint snapshot for this item."
(and on-row-press (and on-row-press
(etaf-ui--data-grid-row-action (etaf-ui--data-grid-row-action
state key row on-row-press))) state key row on-row-press)))
(etaf-ui--table-row-children row columns border-color)))) (etaf-ui--table-row-children row columns))))
(defun etaf-ui--data-grid-state-label (key text &optional class color) (defun etaf-ui--data-grid-state-label (key text &optional class color)
"Return TEXT as a non-row DataGrid state label identified by KEY. "Return TEXT as a non-row DataGrid state label identified by KEY.
@ -244,14 +244,13 @@ LOADING-LABEL, ERROR-LABEL, and EMPTY-LABEL override the state text."
(&key controller entry columns row-ref on-row-press row-selected-p (&key controller entry columns row-ref on-row-press row-selected-p
grid-state) grid-state)
"Render one retained keyed DataGrid ENTRY with a cached row action." "Render one retained keyed DataGrid ENTRY with a cached row action."
:view :render
(expr (if (plist-get (cdr entry) :etaf-data-grid-state)
(if (plist-get (cdr entry) :etaf-data-grid-state) (etaf-ui--data-grid-state-entry-node entry)
(etaf-ui--data-grid-state-entry-node entry) (etaf-ui--data-grid-row
(etaf-ui--data-grid-row grid-state controller entry columns row-ref on-row-press row-selected-p
grid-state controller entry columns row-ref on-row-press row-selected-p (etaf-ui--style-tokens
(etaf-ui--style-tokens :ui-table-border :ui-table-selected-fg :ui-table-selected-bg))))
:ui-table-border :ui-table-selected-fg :ui-table-selected-bg)))))
;;;###autoload ;;;###autoload
(etaf-define-component etaf-data-grid (etaf-define-component etaf-data-grid

View File

@ -46,20 +46,13 @@
(1+ width) (1+ width)
width))) width)))
(defun etaf-ui--table-cell-frame (first-p header-p color) (defun etaf-ui--table-header-cell (column gap-p)
"Return shared Cell border properties for FIRST-P, HEADER-P, and COLOR."
(ignore first-p header-p color)
nil)
(defun etaf-ui--table-header-cell (column first-p gap-p border-color)
"Return one Label header for COLUMN, adding air when GAP-P is non-nil." "Return one Label header for COLUMN, adding air when GAP-P is non-nil."
(etaf-node (etaf-node
'box 'box
(append (list :class "etaf-table-header-cell"
(list :class "etaf-table-header-cell" :width (etaf-ui--table-track-width column gap-p)
:width (etaf-ui--table-track-width column gap-p) :wrap-mode 'none)
:wrap-mode 'none)
(etaf-ui--table-cell-frame first-p t border-color))
(list (list
(etaf-node (etaf-node
'text nil 'text nil
@ -102,21 +95,16 @@
(list (etaf-node 'text nil (list fixed-text))) (list (etaf-node 'text nil (list fixed-text)))
(cl-loop for column in columns (cl-loop for column in columns
for tail on columns for tail on columns
for index from 0
collect collect
(etaf-ui--table-header-cell (etaf-ui--table-header-cell column (cdr tail)))))))
column (zerop index) (cdr tail)
(plist-get theme :ui-table-border)))))))
(defun etaf-ui--table-cell (row column first-p gap-p border-color) (defun etaf-ui--table-cell (row column gap-p)
"Return one Label cell for ROW and COLUMN using GAP-P." "Return one Label cell for ROW and COLUMN using GAP-P."
(etaf-node (etaf-node
'box 'box
(append (list :class "etaf-table-cell"
(list :class "etaf-table-cell" :width (etaf-ui--table-track-width column gap-p)
:width (etaf-ui--table-track-width column gap-p) :wrap-mode 'none)
:wrap-mode 'none)
(etaf-ui--table-cell-frame first-p nil border-color))
(list (list
(etaf-node (etaf-node
'text nil 'text nil
@ -126,14 +114,12 @@
row (etaf-ui--column-value column :key)) row (etaf-ui--column-value column :key))
column)))))) column))))))
(defun etaf-ui--table-cells (row columns border-color) (defun etaf-ui--table-cells (row columns)
"Return cell Components for ROW and COLUMNS." "Return cell Components for ROW using COLUMNS."
(cl-loop for column in columns (cl-loop for column in columns
for tail on columns for tail on columns
for index from 0
collect collect
(etaf-ui--table-cell (etaf-ui--table-cell row column (cdr tail))))
row column (zerop index) (cdr tail) border-color)))
(defun etaf-ui--table-fixed-row-text (row columns) (defun etaf-ui--table-fixed-row-text (row columns)
"Return one fixed-width ROW string for COLUMNS, or nil when not applicable." "Return one fixed-width ROW string for COLUMNS, or nil when not applicable."
@ -155,16 +141,17 @@
(make-string (max 0 (- width (string-width value))) ?\s)))) (make-string (max 0 (- width (string-width value))) ?\s))))
columns " "))) columns " ")))
(defun etaf-ui--table-row-children (row columns border-color) (defun etaf-ui--table-row-children (row columns)
"Return the smallest presentation-equivalent child list for ROW. "Return the smallest presentation-equivalent child list for ROW.
COLUMNS with fixed positive character widths use one padded Text Host; COLUMNS with fixed positive character widths use one padded Text Host;
otherwise retain the general per-cell Box path using BORDER-COLOR." otherwise retain the general per-cell Box path."
(if-let* ((text (etaf-ui--table-fixed-row-text row columns))) (if-let* ((text (etaf-ui--table-fixed-row-text row columns)))
(list (etaf-node 'text nil (list text))) (list (etaf-node 'text nil (list text)))
(etaf-ui--table-cells row columns border-color))) (etaf-ui--table-cells row columns)))
(defun etaf-ui--table-entries (rows row-key) (defun etaf-ui--table-entries (rows row-key)
"Return `(KEY . ROW)' entries; ETAF validates keys and uniqueness." "Return `(KEY . ROW)' entries for ROWS using ROW-KEY.
ETAF validates keys and uniqueness."
(unless (functionp row-key) (unless (functionp row-key)
(error "ETAF Table requires a function-valued :row-key")) (error "ETAF Table requires a function-valued :row-key"))
(mapcar (lambda (row) (cons (funcall row-key row) row)) rows)) (mapcar (lambda (row) (cons (funcall row-key row) row)) rows))
@ -176,7 +163,8 @@ otherwise retain the general per-cell Box path using BORDER-COLOR."
This helper is shared by the retained presentational Table Component and the This helper is shared by the retained presentational Table Component and the
DataGrid's keyed hot path. Keeping the row itself as a Host avoids creating a DataGrid's keyed hot path. Keeping the row itself as a Host avoids creating a
second Component boundary for every visible item while preserving the same second Component boundary for every visible item while preserving the same
selection, event, and style contract." selection, event, and style contract. COLUMNS define the visible cells;
ROW-REF, ON-ROW-PRESS, and ROW-SELECTED-P define optional interaction."
(let* ((callback on-row-press) (let* ((callback on-row-press)
(row-value row) (row-value row)
(interactive-p (not (null callback))) (interactive-p (not (null callback)))
@ -212,8 +200,7 @@ selection, event, and style contract."
:on-press :on-press
(when interactive-p (when interactive-p
(lambda () (funcall callback row-value)))) (lambda () (funcall callback row-value))))
(etaf-ui--table-row-children (etaf-ui--table-row-children row columns))))
row columns (plist-get theme :ui-table-border)))))
(etaf-define-component etaf-ui--table-header (&key columns) (etaf-define-component etaf-ui--table-header (&key columns)
"Render one retained Table header." "Render one retained Table header."

View File

@ -1,5 +1,7 @@
;;; etaf-ui-tests.el --- Official ETAF Component tests -*- lexical-binding: t; -*- ;;; etaf-ui-tests.el --- Official ETAF Component tests -*- lexical-binding: t; -*-
;;; Code:
(require 'ert) (require 'ert)
(require 'etaf-ui) (require 'etaf-ui)