Reusable UI components for ETAF applications: buttons, forms, panels and window shells
ext
  • Emacs Lisp 95.3%
  • Python 4.3%
  • Makefile 0.2%
  • Shell 0.2%
Find a file
Kinneyzhang 09af2e0a06
Some checks failed
Repository structure / structure (push) Has been cancelled
chore(release): bump etaf-ui to 0.3.3 for the archive
The archive refuses a tarball whose bytes changed under an unchanged version,
and eight shipped commits landed after 0.3.2 was published: markdown source
ranges, task-mark geometry, the keycap colour mixer and the table column rule.
Publishing them needs a new version, so the entry declares 0.3.3.

Validation: the version line is the only change in this commit; make -C
etaf-ui check passes on main before it.
2026-11-06 22:10:03 +08:00
.githooks chore(git): enforce logical commits and structured messages 2026-09-13 11:15:13 +08:00
.github/workflows chore(scripts): sync shared workspace tooling 2026-10-13 01:37:28 +08:00
benchmarks test(etaf-ui): verify the sheet's jump by its painted text 2026-10-20 23:18:58 +08:00
examples fix(compat): declare optional display and pretty-print APIs 2026-10-17 15:01:32 +08:00
lisp fix(markdown): paint a soft line break as a line break 2026-11-01 22:40:48 +08:00
scripts chore(scripts): sync shared workspace tooling 2026-10-22 13:15:56 +08:00
tests fix(markdown): paint a soft line break as a line break 2026-11-01 22:40:48 +08:00
.editorconfig chore: establish consistent repository and acceptance policy 2026-09-13 11:10:50 +08:00
.gitignore chore: establish consistent repository and acceptance policy 2026-09-13 11:10:50 +08:00
CHANGELOG.md feat(markdown): give a parsed block its own source range 2026-10-31 17:27:43 +08:00
etaf-ui.el chore(release): bump etaf-ui to 0.3.3 for the archive 2026-11-06 22:10:03 +08:00
LICENSE chore: add the GPL-3.0 license 2026-10-13 00:48:59 +08:00
Makefile fix(etaf-ui): map sheet presses to the right cell 2026-10-20 23:00:09 +08:00
README.md chore(release): version 0.1.1 2026-10-17 16:37:39 +08:00
README.zh-CN.md chore(release): version 0.1.1 2026-10-17 16:37:39 +08:00

etaf-ui

etaf-ui is the official ETAF Component catalog. It is a normal optional package above etaf; it does not add a second Control or Widget model. Button, Checkbox, Label, Panel, and DataGrid are all ordinary Components with the same View, props, slots, events, and Data contracts. It requires Emacs 29.1+, ETAF 0.2.2+, and Ebox 3.0.1+.

Installation

Evaluate this once in Emacs and accept the default component gallery:

;;; -*- lexical-binding: t; -*-
(require 'package)
(add-to-list 'package-archives '("etaf" . "https://etaf.top/packages/"))
(package-initialize)
(package-refresh-contents)
(package-install 'etaf-install)
(call-interactively #'etaf-install)

Package.el installs ETAF and its dependencies without Git, Python or a system compiler; your configuration is not replaced. Reopen with M-x etaf-install or M-x etaf-ui-gallery-open, including offline. Use M-x list-packages to update or remove packages and restart after updates or installation failures. See installation and recovery.

First Component

Use the exact registered names etaf-panel, etaf-label, etaf-button, and etaf-checkbox in every View. Evaluate this complete example in a lexical-binding .el file, then switch to *etaf-preferences* to use its controls.

;;; -*- lexical-binding: t; -*-
(require 'etaf-ui)

(etaf-define-component demo-preferences ()
  :bindings ((done (etaf-ref nil))
             (saved (etaf-ref "Unsaved"))
             (rows (etaf-ref 3)))
  :view
  (etaf-panel :title "Account"
    (slot :name 'header
      (etaf-button :label "Save" :ref 'save-button
                   :on-press (lambda () (setf (etaf-value saved) "Saved"))))
    (etaf-label :text (etaf-value saved))
    (etaf-checkbox :bind done :label "Done" :ref 'done-checkbox)
    (etaf-number-input :bind rows :label "Rows" :ref 'rows-input :min 1 :max 10)
    (text (expr (if (etaf-value done) "Complete" "Pending")))))

(etaf-mount "*etaf-preferences*" (etaf-view (demo-preferences)))

Complete usage and interface contracts.

Run M-x etaf-ui-gallery-open to browse all 63 components in eight categories. The Gallery includes live previews, Chinese/English search, scoped light/dark Themes and reset. Each usage panel includes the public signature, parameter meanings, required/default values, units, callback arguments and constraints, followed by the same runnable, copyable example as the live specimen. Reference text is read from the installed etaf-ui.el Commentary before mounting; no separate API catalog or manual package is needed. It uses local data only. Wide windows show a sidebar and two-column overview; compact windows use a category picker and a scrolling single column. Allow at least 72 character widths and 24 rows; smaller windows deliberately clip the layout. See Gallery workflows and lifecycle.

For in-buffer floating UI, compose etaf-popover, etaf-dropdown-menu and etaf-dialog with ordinary controls and slots. Run M-x etaf-ui-surfaces-open for the menu and preferences example. Placement and occlusion come from Ebox; panel navigation uses its shared focus. Run make gui-check against the existing graphical Emacs server for the maintained keyboard/mouse interaction workflow. Use make gui-check GUI_EXAMPLE=fonts to compare actual physical row heights and an unchanged neighboring row across native control toggles, selection, tabs and dialogs in the current Emacs font configuration. Use make gui-check GUI_EXAMPLE=gallery for the integrated Gallery workflow, including drawer handoff, Chinese input, controlled selection and pagination.

Run make perf-check PERF_ARGS='--diagnose' from the development workspace to measure the existing graphical Emacs. The shared runner uses the registered Gallery callback, keyboard and mouse scenarios, with three sets of ten samples and separate phase, CPU and allocation passes. Budgets remain 50 ms for the checkbox, 100 ms for floating UI and a separate 500 ms hard limit. PERF_TOOL=/path/to/workspace/scripts/performance.py selects the same tool for a separate checkout. The workspace's docs/manual.md documents baseline comparison, source freshness and evidence boundaries.

Gallery selection has separate fresh-page and repeated-toggle workloads: gallery.selection.callback and gallery.selection.mouse create a page per sample; their .steady. counterparts retain one page and alternate checked values. gallery.categories.steady.callback and .mouse cycle through input, data and overview pages. Menu, tooltip, toast and mixed sequences cover overlays. Owned fixtures resolve their viewport before timing; batch uses 160 character widths and 50 rows. These versioned catalog-browser workloads are not comparable with the former Atelier workspace workloads.

Development

After cloning, run make setup-hooks. Before submitting a change, run make check; make structure-check is the fast organization gate.

make check runs structure checks, compilation and the public acceptance scenarios listed in tests/acceptance.json. make test runs the same public API suite. The inventory covers every maintained Lisp test. GUI and performance checks use separate targets.

Source layout

Add the repository root to load-path and require etaf-ui. The root entry loads the implementation in lisp/ and documents the supported public APIs in its Commentary. Package archives include both the root entry and lisp/.