diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f9ab7f9..5d4f4cd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,15 +54,15 @@ }, { "name": "Setup Common Lisp Environment", - "uses": "40ants/setup-lisp@v2", + "uses": "40ants/setup-lisp@v3", "with": { "asdf-system": "reblocks-ui" }, "if": "steps.cache.outputs.cache-hit != 'true'" }, { - "name": "Change dist to Ultralisp", - "run": "echo 'dist ultralisp http://dist.ultralisp.org' > qlfile", + "name": "Change dist to Ultralisp if qlfile does not exist", + "run": "if [[ ! -e qlfile ]]; then echo 'dist ultralisp http://dist.ultralisp.org' > qlfile; fi", "shell": "bash" }, { @@ -72,12 +72,12 @@ }, { "name": "Install SBLint wrapper", - "run": "qlot exec ros install 40ants-linter", + "run": "qlot exec ros install 40ants-asdf-system 40ants-linter", "shell": "bash" }, { "name": "Run Linter", - "run": "qlot exec 40ants-linter --system \"reblocks-ui, reblocks-ui-docs, reblocks-ui-examples\"", + "run": "qlot exec 40ants-linter --system \"reblocks-ui, reblocks-ui-docs, reblocks-ui-examples\" --imports", "shell": "bash" } ] @@ -122,7 +122,7 @@ }, { "name": "Setup Common Lisp Environment", - "uses": "40ants/setup-lisp@v2", + "uses": "40ants/setup-lisp@v3", "with": { "asdf-system": "reblocks-ui" }, @@ -145,7 +145,7 @@ }, { "name": "Run Critic for \"reblocks-ui\" system", - "run": "qlot exec lisp-critic --ignore function-too-long reblocks-ui", + "run": "qlot exec lisp-critic --ignore function-too-long,check-prefix reblocks-ui", "shell": "bash" } ] diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index e39e0d7..c3fba87 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -49,7 +49,7 @@ }, { "name": "Setup Common Lisp Environment", - "uses": "40ants/setup-lisp@v2", + "uses": "40ants/setup-lisp@v3", "with": { "asdf-system": "reblocks-ui-docs" }, diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..954a253 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,39 @@ +{ + "name": "RELEASE", + "on": { + "push": { + "branches": [ + "master" + ] + } + }, + "jobs": { + "autotag": { + "permissions": { + "contents": "write" + }, + "runs-on": "ubuntu-latest", + "env": { + "OS": "ubuntu-latest" + }, + "steps": [ + { + "name": "Checkout Code", + "uses": "actions/checkout@v3" + }, + { + "name": "Create release tag", + "uses": "butlerlogic/action-autotag@8bc1ad456dcdee34e8c6ffbce991cc31793578c2", + "with": { + "root": "ChangeLog.md", + "regex_pattern": "^## (?\\d+\\.\\d+\\.\\d+.*?)( |\\n).*$", + "tag_prefix": "v" + }, + "env": { + "GITHUB_TOKEN": "${{ secrets.GITHUB_TOKEN }}" + } + } + ] + } + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 9c1bf5b..8a7730e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /env/ /.qlot/ .DS_Store +*.fasl diff --git a/docs/changelog.lisp b/docs/changelog.lisp index d3414f8..ccb181d 100644 --- a/docs/changelog.lisp +++ b/docs/changelog.lisp @@ -9,6 +9,16 @@ "JS" "UI" "40ANTS-DOC")) + (0.16.0 2022-12-12 + " +Changed +======= + +- Functions REBLOCKS-UI/FORM:ERROR-PLACEHOLDER and REBLOCKS-UI/FORM:FORM-ERROR-PLACEHOLDER now + can be called not only inside the REBLOCKS-UI/FORM:WITH-HTML-FORM macro body, but also in any + function within. +- Added CSS attribute display none/block for popup. +") (0.15.0 2022-11-26 " New diff --git a/docs/core.lisp b/docs/core.lisp index aad2f19..9c7c58d 100644 --- a/docs/core.lisp +++ b/docs/core.lisp @@ -3,7 +3,6 @@ #:reblocks-ui/core) (:import-from #:40ants-doc #:defsection) - (:import-from #:reblocks) (:export #:@core)) (in-package #:reblocks-ui-docs/core) diff --git a/docs/form.lisp b/docs/form.lisp index 840a141..de26445 100644 --- a/docs/form.lisp +++ b/docs/form.lisp @@ -2,7 +2,6 @@ (:use #:cl) (:import-from #:40ants-doc #:defsection) - (:import-from #:reblocks) (:import-from #:reblocks/doc/example #:defexample) (:import-from #:reblocks-ui/form @@ -12,6 +11,8 @@ #:field-error) (:import-from #:reblocks/html #:with-html) + (:import-from #:reblocks-ui/core) + (:import-from #:reblocks/widget) (:export #:@form)) (in-package #:reblocks-ui-docs/form) diff --git a/docs/index.lisp b/docs/index.lisp index 18262cb..6857157 100644 --- a/docs/index.lisp +++ b/docs/index.lisp @@ -2,7 +2,6 @@ (:use #:cl) (:import-from #:40ants-doc #:defsection) - (:import-from #:reblocks) (:import-from #:reblocks/doc/example #:defexample) (:import-from #:docs-config @@ -20,6 +19,7 @@ #:@form) (:import-from #:reblocks-ui-docs/core #:@core) + (:import-from #:reblocks/widget) (:export #:@index #:@readme)) (in-package #:reblocks-ui-docs/index) diff --git a/examples/form-errors.lisp b/examples/form-errors.lisp index 16cd109..4d45f97 100644 --- a/examples/form-errors.lisp +++ b/examples/form-errors.lisp @@ -2,6 +2,8 @@ (:use #:cl) (:import-from #:reblocks/app #:defapp) + (:import-from #:reblocks/server) + (:import-from #:reblocks/session) (:import-from #:reblocks/widget #:update #:defwidget) diff --git a/qlfile.lock b/qlfile.lock index b59875f..14edcee 100644 --- a/qlfile.lock +++ b/qlfile.lock @@ -1,8 +1,8 @@ ("quicklisp" . (:class qlot/source/dist:source-dist :initargs (:distribution "http://beta.quicklisp.org/dist/quicklisp.txt" :%version :latest) - :version "2022-11-07")) + :version "2023-10-21")) ("ultralisp" . (:class qlot/source/dist:source-dist :initargs (:distribution "http://dist.ultralisp.org" :%version :latest) - :version "20221126115000")) + :version "20231212181000")) diff --git a/reblocks-ui-docs.asd b/reblocks-ui-docs.asd index c68f995..16b04f5 100644 --- a/reblocks-ui-docs.asd +++ b/reblocks-ui-docs.asd @@ -9,3 +9,6 @@ :description "Documentation for Reblocks UI widgets." :homepage "https://40ants.com/reblocks-ui/" :source-control (:git "https://github.com/40ants/reblocks-ui")) + + + diff --git a/reblocks-ui.asd b/reblocks-ui.asd index cd9b94d..a1eb646 100644 --- a/reblocks-ui.asd +++ b/reblocks-ui.asd @@ -29,3 +29,6 @@ (read-sequence seq stream)) seq))) :in-order-to ((test-op (test-op reblocks-ui-test)))) + + +(asdf:register-system-packages "log4cl" '("LOG")) diff --git a/src/ci.lisp b/src/ci.lisp index fefdc62..f8de6cd 100644 --- a/src/ci.lisp +++ b/src/ci.lisp @@ -8,11 +8,17 @@ #:build-docs) (:import-from #:40ants-ci/workflow #:defworkflow) + (:import-from #:40ants-ci/jobs/autotag) (:import-from #:40ants-ci/jobs/critic #:critic)) (in-package reblocks-ui/ci) +(defworkflow release + :on-push-to "master" + :jobs ((40ants-ci/jobs/autotag:autotag))) + + (defworkflow docs :on-push-to "master" :on-pull-request t @@ -27,9 +33,11 @@ :cache t :jobs ((linter :asdf-systems ("reblocks-ui" "reblocks-ui-docs" - "reblocks-ui-examples")) + "reblocks-ui-examples") + :check-imports t) (critic :ignore-critiques ;; Seems Lisp Critic counts docstring lines too :( - ("function-too-long")) + ("function-too-long" + "check-prefix")) ;; (run-tests :coverage t) )) diff --git a/src/core.lisp b/src/core.lisp index fa611d4..dbb64dc 100644 --- a/src/core.lisp +++ b/src/core.lisp @@ -3,6 +3,7 @@ (:nicknames #:reblocks-ui) (:import-from #:reblocks-parenscript) + (:import-from #:log) (:import-from #:parenscript #:chain) (:import-from #:reblocks/widget diff --git a/src/form.lisp b/src/form.lisp index 23fee8a..8dc4d1b 100644 --- a/src/form.lisp +++ b/src/form.lisp @@ -1,6 +1,7 @@ (defpackage #:reblocks-ui/form (:use #:cl) - (:import-from #:log4cl) + (:import-from #:log) + (:import-from #:spinneret) (:import-from #:reblocks/actions #:make-action-url #:make-action) @@ -303,6 +304,9 @@ $('~A').foundation(); (error-placeholder-message widget))))) +(defvar *error-placeholder-func*) + + (defun error-placeholder (name &key (widget-class 'error-placeholder)) "This function creates and renders a widget to show an error message related to some form field. @@ -311,9 +315,14 @@ $('~A').foundation(); NAME argument should be a string denoting a form field. Later, you can call FIELD-ERROR function to signal an error from the action function. You will need to pass the NAME as the first argument to the FIELD-ERROR function." - (declare (ignore name widget-class)) - (error "This function should be called inside WITH-HTML-FORM macro.")) + (cond + ((boundp '*error-placeholder-func*) + (funcall *error-placeholder-func* name :widget-class widget-class)) + (t + (error "This function should be called inside WITH-HTML-FORM macro.")))) + +(defvar *form-error-placeholder-func*) (defun form-error-placeholder (&key (widget-class 'form-error-placeholder)) "This function creates and renders a widget to show an error for the whole form. @@ -321,8 +330,11 @@ $('~A').foundation(); It should be called inside WITH-HTML-FORM macro. Later, you can call FORM-ERROR function to signal an error from the action function." - (declare (ignore widget-class)) - (error "This function should be called inside WITH-HTML-FORM macro.")) + (cond + ((boundp '*form-error-placeholder-func*) + (funcall *form-error-placeholder-func* :widget-class widget-class)) + (t + (error "This function should be called inside WITH-HTML-FORM macro.")))) (defun %render-error-placeholder (name widget-class error-placeholders) @@ -391,21 +403,20 @@ $('~A').foundation(); (%render-error-placeholder name widget-class error-placeholders)) (form-error-placeholder (&key (widget-class 'form-error-placeholder)) (%render-form-error-placeholder widget-class error-placeholders))) - (declare (ignorable (function error-placeholder) - (function form-error-placeholder))) - - (%render-form ,method-type - ,action - ,body - :id ,id - :class ,class - :enctype ,enctype - :use-ajax-p ,use-ajax-p - :extra-submit-code ,extra-submit-code - :requires-confirmation-p ,requires-confirmation-p - :confirm-question ,confirm-question - :submit-fn ,submit-fn - :error-placeholders error-placeholders))))) + (let ((*error-placeholder-func* #'error-placeholder) + (*form-error-placeholder-func* #'form-error-placeholder)) + (%render-form ,method-type + ,action + ,body + :id ,id + :class ,class + :enctype ,enctype + :use-ajax-p ,use-ajax-p + :extra-submit-code ,extra-submit-code + :requires-confirmation-p ,requires-confirmation-p + :confirm-question ,confirm-question + :submit-fn ,submit-fn + :error-placeholders error-placeholders)))))) (defun render-button (name &key diff --git a/src/popup.lisp b/src/popup.lisp index 5712036..129dd8d 100644 --- a/src/popup.lisp +++ b/src/popup.lisp @@ -71,6 +71,7 @@ :height 100vh :background "rgba(0,0,0,0.5)" :opacity 0 + :display none :pointer-events none :transition 0.5s all @@ -88,6 +89,7 @@ :padding 25px :transition 0.5s all)) ((:and .popup .active) + :display block :opacity 1 :pointer-events all :transition 0.5s all