Deliver the unified View and Component model with retained Runtime, reactive scopes, Context, Behaviors, events, Actions, styles, Resources, Data, official UI Components, and Playground examples.\n\nVerification: make check and make load pass in the independent repository; sibling Ebox core tests pass 544/544.
115 lines
3.6 KiB
EmacsLisp
115 lines
3.6 KiB
EmacsLisp
;;; etaf-playground.el --- Small ETAF application examples -*- lexical-binding: t; -*-
|
|
|
|
;; SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
;;; Commentary:
|
|
|
|
;; The ETAF playground is an optional application example. It exercises only
|
|
;; public ETAF APIs; the Ebox playground remains a separate sibling package.
|
|
|
|
;;; Code:
|
|
|
|
(require 'cl-lib)
|
|
(require 'etaf)
|
|
|
|
(defconst etaf-playground-buffer-name "*ETAF Playground*"
|
|
"Default buffer name used by `etaf-playground-open'.")
|
|
|
|
;;;###autoload
|
|
(etaf-define-component etaf-playground-counter (&key title)
|
|
"Render a small stateful counter titled TITLE.
|
|
|
|
The counter demonstrates a retained `:setup' Scope, reactive state, semantic
|
|
Host references, and ordinary `:on-press' callbacks without introducing a
|
|
special counter node or a second event model."
|
|
:setup
|
|
(let ((count (etaf-ref 0 :name 'playground-count)))
|
|
(lambda ()
|
|
(etaf-view
|
|
(column
|
|
:class "etaf-playground-counter"
|
|
(text :face 'bold (expr :value title))
|
|
(text
|
|
(expr :value (format "Count: %d" (etaf-value count))))
|
|
(row
|
|
(text
|
|
:ref 'decrement
|
|
:role 'button
|
|
:tab-index 0
|
|
:on-press (lambda () (cl-decf (etaf-value count)))
|
|
" - ")
|
|
(text
|
|
:ref 'increment
|
|
:role 'button
|
|
:tab-index 0
|
|
:on-press (lambda () (cl-incf (etaf-value count)))
|
|
" + ")))))))
|
|
|
|
;;;###autoload
|
|
(defun etaf-playground-view ()
|
|
"Return the core ETAF playground View.
|
|
|
|
The returned View has no buffer or global state side effect until it is passed
|
|
to `etaf-mount'."
|
|
(etaf-view
|
|
(column
|
|
:class "etaf-playground-root"
|
|
(text :face 'bold "ETAF Playground")
|
|
(text :color "#687386"
|
|
"One grammar: Hosts, Components, props, children, and expr.")
|
|
(etaf-playground-counter :title "Reactive counter")
|
|
(text :color "#687386"
|
|
"Press + or - with `etaf-dispatch-event' or the normal event bridge."))))
|
|
|
|
;;;###autoload
|
|
(defun etaf-playground-ui-view ()
|
|
"Return a playground View that also demonstrates the official UI catalog.
|
|
|
|
Loading this function requires `etaf-ui'; the core playground itself does not
|
|
depend on that optional Component catalog."
|
|
(require 'etaf-ui)
|
|
(etaf-view
|
|
(column
|
|
(etaf-panel :title "Official Components"
|
|
(etaf-button
|
|
:label "A public Component"
|
|
:on-press (lambda () (message "ETAF UI button pressed")))
|
|
(etaf-checkbox
|
|
:checked nil
|
|
:label "Controlled checkbox"
|
|
:on-change (lambda (value)
|
|
(message "Checkbox value: %s" value))))
|
|
(etaf-playground-counter :title "Core counter"))))
|
|
|
|
;;;###autoload
|
|
(defun etaf-playground-open (&optional buffer-name)
|
|
"Mount the core ETAF playground in BUFFER-NAME and return its buffer."
|
|
(interactive)
|
|
(etaf-mount (or buffer-name etaf-playground-buffer-name)
|
|
(etaf-playground-view)))
|
|
|
|
;;;###autoload
|
|
(defun etaf-playground-open-ui (&optional buffer-name)
|
|
"Mount the ETAF playground with official UI Components in BUFFER-NAME."
|
|
(interactive)
|
|
(etaf-mount (or buffer-name etaf-playground-buffer-name)
|
|
(etaf-playground-ui-view)))
|
|
|
|
;;;###autoload
|
|
(defun etaf-playground-close (&optional buffer-name)
|
|
"Unmount and kill the playground BUFFER-NAME, returning its buffer.
|
|
|
|
When BUFFER-NAME is nil, use `etaf-playground-buffer-name'."
|
|
(interactive)
|
|
(let* ((name (or buffer-name etaf-playground-buffer-name))
|
|
(buffer (get-buffer name)))
|
|
(when-let ((runtime (and buffer (etaf-runtime-for-buffer buffer))))
|
|
(etaf-unmount runtime))
|
|
(when buffer
|
|
(kill-buffer buffer))
|
|
buffer))
|
|
|
|
(provide 'etaf-playground)
|
|
|
|
;;; etaf-playground.el ends here
|