dev.metalisp.sbt/src/component/accordion.lisp

53 lines
2.4 KiB
Common Lisp
Raw Normal View History

2023-09-01 13:44:27 +02:00
;;;; accordion.lisp
;;;;
;;;; This file defines a package for generating Bootstrap accordion components
2023-09-09 08:20:17 +02:00
;;;; using Common Lisp macros.
2023-07-11 15:59:52 +02:00
2023-12-18 11:34:54 +01:00
(defpackage dev.metalisp.sbt/component/accordion
2023-09-01 15:20:45 +02:00
(:documentation "A package for generating Bootstrap accordions.")
2023-07-11 15:59:52 +02:00
(:use :cl)
(:export
:accordion))
2023-12-18 11:34:54 +01:00
(in-package :dev.metalisp.sbt/component/accordion)
2023-07-11 15:59:52 +02:00
2024-02-03 20:57:11 +01:00
(defmacro accordion ((&key (id "accordionExample") flush) &body body)
"This macro generates an accordion-style collapsible list.
2024-02-03 18:56:58 +01:00
ID: Specifies a unique identifier for the accordion. Defaults to 'accordionExample'.
FLUSH: If t, adds class 'accordion-flush' to remove borders. Defaults to nil.
2024-02-03 20:57:11 +01:00
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\")"
(let ((class (if flush "accordion accordion-flush" "accordion")))
2024-02-03 18:53:45 +01:00
`(spinneret:with-html
(:div :class ,class
:id ,id
,@(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"))
2024-02-03 18:53:45 +01:00
collect `(:div :class "accordion-item"
2024-02-03 20:50:10 +01:00
(:h2 :class "accordion-header"
(:button :class ,btn-class
2024-02-03 20:50:10 +01:00
:type "button"
:data-bs-toggle "collapse"
:data-bs-target ,(concatenate 'string "#" collapse-id)
:aria-expanded ,(if (= counter 1) "true" "false")
:aria-controls ,collapse-id
2024-02-03 20:50:10 +01:00
,title))
(:div :id ,collapse-id
:class ,collapse-class
:data-bs-parent ,(concatenate 'string "#" id)
(:div :class "accordion-body"
,content))))))))