Simply use a sequence of strings for accordion

This commit is contained in:
Marcus Kammer 2024-02-04 18:35:29 +01:00
parent 1532c329f8
commit 9da0853591
2 changed files with 13 additions and 42 deletions

View file

@ -18,23 +18,27 @@ ID: Specifies a unique identifier for the accordion. Defaults to 'accordionExamp
FLUSH: If t, adds class 'accordion-flush' to remove borders. Defaults to nil.
BODY: Sequence of strings where every pair represents a title and content for
the accordion item.
---
5 Scenarios to Avoid Them: https://www.nngroup.com/videos/avoid-accordions/
---
Example usage:
(accordion () (\"Title 1\" \"Content 1\") (\"Title 2\" \"Content 2\"))
(accordion (:id \"accordionExample\" :flush t) (\"Title 1\" \"Content 1\") (\"Title 2\" \"Content 2\"))"
(let ((class (concatenate 'string "accordion" (when flush " accordion-flush"))))
(accordion () \"Title 1\" \"Content 1\" \"Title 2\" \"Content 2\")"
(let ((class (if flush "accordion accordion-flush" "accordion")))
`(spinneret:with-html
(:div :class ,class
:id ,id
,@(loop for (title content) in body
,@(loop for (title content) on body by #'cddr
for counter from 1
for collapse-id = (format nil "collapse-~a-~a" id counter)
for collapse-class = (concatenate 'string "accordion-collapse collapse" (when (= counter 1) " show"))
for btn-class = (concatenate 'string "accordion-button" (when (not (= counter 1)) " collapsed"))
collect `(:div :class "accordion-item"
(:h2 :class "accordion-header"
(:button :class "accordion-button"
(:button :class ,btn-class
:type "button"
:data-bs-toggle "collapse"
:data-bs-target ,(concatenate 'string "#" collapse-id)
@ -42,7 +46,7 @@ Example usage:
:aria-controls ,collapse-id
,title))
(:div :id ,collapse-id
:class "accordion-collapse collapse"
:class ,collapse-class
:data-bs-parent ,(concatenate 'string "#" id)
(:div :class "accordion-body"
,content))))))))

View file

@ -5,45 +5,12 @@
:rove)
(:import-from
:dev.metalisp.sbt/component/accordion
:header
:collapse
:item
:accordion))
(in-package :dev.metalisp.sbt/tests/accordion)
(deftest test-header
(let ((result (spinneret:with-html-string (header "collapseOne" "Heading" t))))
(testing "Generates correct HTML for accordion header"
(ok (search "class=accordion-header" result))
(ok (search "class=accordion-button" result))
(ok (search "data-bs-target=#collapseOne" result))
(ok (search "aria-expanded=true" result))
(ok (search "aria-controls=#collapseOne" result))
(ok (search "Heading" result)))))
(deftest test-collapse
(let ((result (spinneret:with-html-string (collapse "accordionExample" "collapseOne" t))))
(testing "Generates correct HTML for accordion collapse"
(ok (search "class=\"accordion-collapse collapse show\"" result))
(ok (search "id=collapseOne" result))
(ok (search "data-bs-parent=#accordionExample" result))
(ok (search "class=accordion-body" result)))))
(deftest test-item
(let ((result (spinneret:with-html-string (item (header "collapseOne" "Heading" t) (collapse "accordionExample" "collapseOne" t "Some content")))))
(testing "Generates correct HTML for accordion item"
(ok (search "class=accordion-item" result))
(ok (search "class=accordion-header" result))
(ok (search "class=accordion-button" result))
(ok (search "class=\"accordion-collapse collapse show\"" result))
(ok (search "data-bs-target=#collapseOne" result))
(ok (search "aria-expanded=true" result))
(ok (search "aria-controls=#collapseOne" result))
(ok (search "Some content" result)))))
(deftest test-accordion-correct-classes
(let ((result (with-output-to-string (spinneret:*html*) (accordion (:id "accordionExample" :flush t) ("Accordion Item #1" "Accordion Content #1") ("Accordion Item #2" "Accordion Content #2") ("Accordion Item #3" "Accordion Content #3")))))
(let ((result (with-output-to-string (spinneret:*html*) (accordion (:id "accordionExample" :flush t) "Accordion Item #1" "Accordion Content #1" "Accordion Item #2" "Accordion Content #2" "Accordion Item #3" "Accordion Content #3"))))
(testing "Generates correct HTML for accordion"
(ok (search "class=accordion" result))
(ok (search "class=accordion-item" result))
@ -51,14 +18,14 @@
(ok (search "class=accordion-button" result)))))
(deftest test-accordion-correct-id
(let ((result (with-output-to-string (spinneret:*html*) (accordion (:id "accordionExample" :flush t) ("Accordion Item #1" "Accordion Content #1") ("Accordion Item #2" "Accordion Content #2") ("Accordion Item #3" "Accordion Content #3")))))
(let ((result (with-output-to-string (spinneret:*html*) (accordion (:id "accordionExample" :flush t) "Accordion Item #1" "Accordion Content #1" "Accordion Item #2" "Accordion Content #2" "Accordion Item #3" "Accordion Content #3"))))
(testing "Generates correct HTML for accordion"
(ok (search "id=accordionExample" result))
(ok (search "id=collapse-accordionExample-1" result))
(ok (search "id=collapse-accordionExample-2" result)))))
(deftest test-accordion-correct-aria
(let ((result (with-output-to-string (spinneret:*html*) (accordion (:id "accordionExample" :flush t) ("Accordion Item #1" "Accordion Content #1") ("Accordion Item #2" "Accordion Content #2") ("Accordion Item #3" "Accordion Content #3")))))
(let ((result (with-output-to-string (spinneret:*html*) (accordion (:id "accordionExample" :flush t) "Accordion Item #1" "Accordion Content #1" "Accordion Item #2" "Accordion Content #2" "Accordion Item #3" "Accordion Content #3"))))
(testing "Generates correct HTML for accordion"
(ok (search "aria-expanded=true" result))
(ok (search "aria-expanded=false" result))