Rename elm to element, add render method

This commit is contained in:
paku 2024-05-29 10:30:06 +09:00
parent 1acb065464
commit cc4b3e19c6
2 changed files with 39 additions and 29 deletions

View file

@ -4,7 +4,8 @@
#:element-type #:element-type
#:element-props #:element-props
#:element-children #:element-children
#:expand-component)) #:expand-component
#:render))
(in-package #:hsx/element) (in-package #:hsx/element)
@ -33,16 +34,16 @@
;;;; factory ;;;; factory
(defun create-element (type props &rest children) (defun create-element (type props &rest children)
(let ((elm (make-instance (cond ((functionp type) 'component) (let ((element (make-instance (cond ((functionp type) 'component)
((eq type :<>) 'fragment) ((eq type :<>) 'fragment)
((eq type :html) 'html-tag) ((eq type :html) 'html-tag)
((keywordp type) 'tag) ((keywordp type) 'tag)
(t (error "element-type must be either a keyword or a function."))) (t (error "element-type must be either a keyword or a function.")))
:type type :type type
:props props :props props
:children (flatten children)))) :children (flatten children))))
(create-element-hook elm) (create-element-hook element)
elm)) element))
(defun flatten (x) (defun flatten (x)
(labels ((rec (x acc) (labels ((rec (x acc)
@ -53,23 +54,23 @@
(rec (cdr x) acc)))))) (rec (cdr x) acc))))))
(rec x nil))) (rec x nil)))
(defmethod create-element-hook ((elm element))) (defmethod create-element-hook ((element element)))
(defmethod create-element-hook ((elm fragment)) (defmethod create-element-hook ((element fragment))
(when (element-props elm) (when (element-props element)
(error "Cannot pass props to fragment."))) (error "Cannot pass props to fragment.")))
(defmethod create-element-hook ((elm component)) (defmethod create-element-hook ((element component))
;dry-run to validate props ;dry-run to validate props
(expand-component elm)) (expand-component element))
;;;; methods ;;;; methods
(defmethod print-object ((elm tag) stream) (defmethod print-object ((element tag) stream)
(with-accessors ((type element-type) (with-accessors ((type element-type)
(props element-props) (props element-props)
(children element-children)) elm (children element-children)) element
(let ((type-str (string-downcase type))) (let ((type-str (string-downcase type)))
(if children (if children
(format stream (format stream
@ -100,12 +101,12 @@
key-str key-str
value)))))) value))))))
(defmethod print-object ((elm html-tag) stream) (defmethod print-object ((element html-tag) stream)
(format stream "<!DOCTYPE html>~%") (format stream "<!DOCTYPE html>~%")
(call-next-method)) (call-next-method))
(defmethod print-object ((elm fragment) stream) (defmethod print-object ((element fragment) stream)
(with-accessors ((children element-children)) elm (with-accessors ((children element-children)) element
(if children (if children
(format stream (format stream
(if (rest children) (if (rest children)
@ -113,16 +114,20 @@
"~<~a~:>") "~<~a~:>")
children)))) children))))
(defmethod print-object ((elm component) stream) (defmethod print-object ((element component) stream)
(print-object (expand-component elm) stream)) (print-object (expand-component element) stream))
(defmethod expand-component ((elm component)) (defmethod expand-component ((element component))
(with-accessors ((type element-type) (with-accessors ((type element-type)
(props element-props) (props element-props)
(children element-children)) elm (children element-children)) element
(apply type (merge-children-into-props props children)))) (apply type (merge-children-into-props props children))))
(defun merge-children-into-props (props children) (defun merge-children-into-props (props children)
(append props (append props
(and children (and children
(list :children children)))) (list :children children))))
(defmethod render ((element element) &key minify)
(with-output-to-string (stream)
(write element :stream stream :pretty (not minify))))

View file

@ -1,7 +1,12 @@
(uiop:define-package :hsx (defpackage :hsx
(:nicknames #:hsx/main) (:nicknames #:hsx/main)
(:use #:cl) (:use #:cl
(:use-reexport #:hsx/defhsx) #:hsx/element
#:hsx/defhsx
#:hsx/hsx)
(:import-from #:hsx/builtin) (:import-from #:hsx/builtin)
(:use-reexport #:hsx/hsx)) (:export #:hsx
#:deftag
#:defcomp
#:render))
(in-package :hsx) (in-package :hsx)