2024-02-05 18:34:46 +01:00
|
|
|
;;;; -*- mode: lisp; coding: utf-8; tab-width: 4; fill-column: 100; indent-tabs-mode: nil; -*-
|
2023-09-01 13:44:27 +02:00
|
|
|
;;;; accordion.lisp
|
2024-02-05 18:34:46 +01:00
|
|
|
;;;; This file defines a package for generating Bootstrap accordion components using Common Lisp macros.
|
2024-04-21 11:33:19 +02:00
|
|
|
(defpackage dev.metalisp.sbt/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))
|
|
|
|
|
2024-04-21 11:33:19 +02:00
|
|
|
(in-package :dev.metalisp.sbt/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)
|
2024-02-03 23:42:32 +01:00
|
|
|
"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'.
|
|
|
|
|
2024-02-03 23:42:32 +01:00
|
|
|
FLUSH: If t, adds class 'accordion-flush' to remove borders. Defaults to nil.
|
2024-02-03 20:57:11 +01:00
|
|
|
|
2024-02-04 18:35:29 +01:00
|
|
|
BODY: Sequence of strings where every pair represents a title and content for
|
|
|
|
the accordion item.
|
|
|
|
|
2024-02-03 23:42:32 +01:00
|
|
|
---
|
|
|
|
5 Scenarios to Avoid Them: https://www.nngroup.com/videos/avoid-accordions/
|
|
|
|
---
|
|
|
|
|
|
|
|
Example usage:
|
2024-02-04 18:35:29 +01:00
|
|
|
(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
|
2024-02-04 18:35:29 +01:00
|
|
|
,@(loop for (title content) on body by #'cddr
|
2024-02-03 23:42:32 +01:00
|
|
|
for counter from 1
|
|
|
|
for collapse-id = (format nil "collapse-~a-~a" id counter)
|
2024-02-04 18:35:29 +01:00
|
|
|
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"
|
2024-02-04 18:35:29 +01:00
|
|
|
(:button :class ,btn-class
|
2024-02-03 20:50:10 +01:00
|
|
|
:type "button"
|
|
|
|
:data-bs-toggle "collapse"
|
2024-02-03 23:42:32 +01:00
|
|
|
:data-bs-target ,(concatenate 'string "#" collapse-id)
|
2024-02-04 11:57:03 +01:00
|
|
|
:aria-expanded ,(if (= counter 1) "true" "false")
|
2024-02-03 23:42:32 +01:00
|
|
|
:aria-controls ,collapse-id
|
2024-02-03 20:50:10 +01:00
|
|
|
,title))
|
2024-02-03 23:42:32 +01:00
|
|
|
(:div :id ,collapse-id
|
2024-02-04 18:35:29 +01:00
|
|
|
:class ,collapse-class
|
2024-02-03 23:42:32 +01:00
|
|
|
:data-bs-parent ,(concatenate 'string "#" id)
|
|
|
|
(:div :class "accordion-body"
|
|
|
|
,content))))))))
|