2023-07-07 19:37:58 +02:00
|
|
|
;; https://getbootstrap.com/docs/5.3/components/card/
|
|
|
|
|
2023-07-13 14:10:05 +02:00
|
|
|
;; A Bootstrap Card is a flexible and extensible content container that
|
|
|
|
;; includes multiple options for headers and footers, a variety of content,
|
|
|
|
;; contextual background colors, and powerful display options. Introduced in
|
|
|
|
;; Bootstrap 4, cards are designed to replace old components such as panels,
|
|
|
|
;; wells, and thumbnails.
|
2023-07-11 20:06:31 +02:00
|
|
|
|
|
|
|
;; Cards are made up of multiple parts and can include:
|
|
|
|
|
2023-07-13 14:10:05 +02:00
|
|
|
;; Card Title: Serves as the header for the card and is typically used to
|
|
|
|
;; include the name or the main purpose of the card.
|
2023-07-11 20:06:31 +02:00
|
|
|
|
|
|
|
;; Card Subtitle: Usually follows the title and provides additional context or
|
|
|
|
;; information.
|
|
|
|
|
|
|
|
;; Card Text: This is the main content area for the card. It can include text,
|
|
|
|
;; links, buttons, and more.
|
|
|
|
|
|
|
|
;; Card Image: An optional image can be included at the top of a card.
|
|
|
|
|
|
|
|
;; Card Link: This is typically a call to action or a way to direct the user to
|
|
|
|
;; more information.
|
|
|
|
|
2023-07-13 14:10:05 +02:00
|
|
|
;; Card Header and Card Footer: These optional sections can be added to the top
|
|
|
|
;; or bottom of a card.
|
2023-07-11 20:06:31 +02:00
|
|
|
|
|
|
|
;; In terms of design, cards provide built-in Bootstrap styles, such as borders
|
|
|
|
;; and flexbox, along with optional headers and footers. They offer a lot of
|
|
|
|
;; flexibility and can be used in a wide range of designs and layouts.
|
2023-07-07 19:37:58 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defpackage cl-sbt-card
|
|
|
|
(:use :cl)
|
|
|
|
(:export
|
|
|
|
:title
|
|
|
|
:subtitle
|
|
|
|
:text
|
|
|
|
:link
|
|
|
|
:header
|
|
|
|
:img
|
|
|
|
:body
|
|
|
|
:card-with-img
|
2023-07-14 18:54:17 +02:00
|
|
|
:card
|
2023-07-14 18:58:38 +02:00
|
|
|
:card-group)
|
|
|
|
(:documentation "A Common Lisp package for generating Bootstrap Card components.
|
|
|
|
|
|
|
|
Bootstrap's Card component is a flexible and extensible container for content, introduced in Bootstrap 4 as a replacement for panels, wells, and thumbnails. This package provides macros for generating card components, including card title, subtitle, text, link, header, image, and body.
|
|
|
|
|
|
|
|
The `title`, `subtitle`, `text`, `link`, and `header` macros generate corresponding elements of a Bootstrap card.
|
|
|
|
|
|
|
|
The `img` macro generates a card image element, with an optional source URL and alternative text.
|
|
|
|
|
|
|
|
The `body` macro generates the main content area for the card.
|
|
|
|
|
|
|
|
The `card-with-img` macro generates a card with an image and body content.
|
|
|
|
|
|
|
|
The `card` macro generates a card with body content.
|
|
|
|
|
|
|
|
The `card-group` macro generates a group of cards, each with a title, text, and optional image and link.
|
|
|
|
|
|
|
|
Example usage can be found in the documentation for each macro."))
|
2023-07-07 19:37:58 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(in-package :cl-sbt-card)
|
|
|
|
|
|
|
|
(defmacro title (&body body)
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card title.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
BODY: The contents of the title.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(title \"My Title\")"
|
2023-07-07 20:45:03 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:h5 :class "card-title" ,@body)))
|
2023-07-07 20:45:03 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defmacro subtitle (&body body)
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card subtitle.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
BODY: The contents of the subtitle.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(subtitle \"My Subtitle\")"
|
2023-07-07 20:45:03 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:h6 :class "card-subtitle mb-2 text-body-secondary" ,@body)))
|
2023-07-07 20:45:03 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defmacro text (&body body)
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card text.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
BODY: The contents of the text.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(text \"Some card text here\")"
|
2023-07-07 20:45:03 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:p :class "card-text" ,@body)))
|
2023-07-07 20:45:03 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defmacro link ((&key (href "#")) &body body)
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card link.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
HREF: The URL that the link will point to.
|
|
|
|
BODY: The contents of the link.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(link (:href \"https://example.com\") \"Example link\")"
|
2023-07-07 20:45:03 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:a :href ,href :class "card-link" ,@body)))
|
2023-07-07 20:45:03 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defmacro header (&body body)
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card header.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
BODY: The contents of the header.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(header \"My Card Header\")"
|
2023-07-08 06:59:03 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:div :class "header" ,@body)))
|
2023-07-08 06:59:03 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defmacro img ((&key (src "#") (alt "Card Image")))
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card image.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
SRC: The URL of the image.
|
|
|
|
ALT: The alt text for the image.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(img (:src \"https://example.com/image.jpg\" :alt \"An example image\"))"
|
2023-07-08 06:59:03 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:img :src ,src
|
|
|
|
:alt ,alt
|
|
|
|
:class "card-img-top")))
|
2023-07-08 06:59:03 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defmacro body (&body body)
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card body.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
BODY: The contents of the body.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(body (title \"My Title\") (text \"Some card text here\"))"
|
2023-07-08 06:59:03 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:div :class "card-body" ,@body)))
|
2023-07-08 06:59:03 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defmacro card-with-img ((&key (img-src nil)) &body body)
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card with an image.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
IMG-SRC: The URL of the image.
|
|
|
|
BODY: The contents of the body.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(card-with-img (:img-src \"https://example.com/image.jpg\") (title \"My Title\") (text \"Some card text here\"))"
|
2023-07-07 19:37:58 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:div :class "card"
|
|
|
|
,(if (null img-src) nil `(img (:src ,img-src)))
|
|
|
|
(:div :class "card-body" ,@body))))
|
2023-07-08 06:59:03 +02:00
|
|
|
|
2023-07-11 18:48:32 +02:00
|
|
|
(defmacro card (&body body)
|
2023-07-13 14:10:05 +02:00
|
|
|
"This macro generates a Bootstrap card.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
BODY: The contents of the card.
|
2023-07-11 19:14:01 +02:00
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
Example:
|
|
|
|
(card (title \"My Title\") (text \"Some card text here\"))"
|
2023-07-08 06:59:03 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:div :class "card" ,@body)))
|
2023-07-08 06:59:03 +02:00
|
|
|
|
2023-07-13 21:57:37 +02:00
|
|
|
(defmacro card-group ((&key (id "cardGroupExample")) &rest rest)
|
|
|
|
"This macro generates a group of Bootstrap cards.
|
|
|
|
|
2023-07-14 10:06:50 +02:00
|
|
|
ID: Specifies a unique identifier for the card group. Defaults to 'cardGroupExample'.
|
|
|
|
REST: Specifies a list of card items. Each item is a plist with the following keys:
|
|
|
|
- :img-src: Specifies the URL of the image.
|
|
|
|
- :title: Specifies the title of the card.
|
|
|
|
- :text: Specifies the text of the card.
|
|
|
|
- :link: Specifies a link with a URL and label.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
(card-group (:id \"cardGroupExample\")
|
|
|
|
(:img-src \"...\" :title \"Card #1\" :text \"Some quick example text.\" :link (:href \"#\" :label \"Go somewhere\"))
|
|
|
|
(:img-src \"...\" :title \"Card #2\" :text \"Some quick example text.\" :link (:href \"#\" :label \"Go somewhere\"))
|
|
|
|
(:img-src \"...\" :title \"Card #3\" :text \"Some quick example text.\" :link (:href \"#\" :label \"Go somewhere\")))"
|
2023-07-13 21:57:37 +02:00
|
|
|
`(spinneret:with-html
|
2023-07-13 21:57:54 +02:00
|
|
|
(:div :class "card-group"
|
|
|
|
:id ,id
|
|
|
|
,@(loop for item in rest
|
2023-07-14 18:54:17 +02:00
|
|
|
collect (destructuring-bind (&key img-src body-title body-text link-href link-label) item
|
2023-07-13 21:57:54 +02:00
|
|
|
`(card (img (:src ,img-src))
|
2023-07-14 18:54:17 +02:00
|
|
|
(body (title ,bdy-title)
|
|
|
|
(text ,body-text)
|
2023-07-13 21:57:54 +02:00
|
|
|
(link (:href ,link-href) ,link-label))))))))
|
2023-07-13 21:57:37 +02:00
|
|
|
|
2023-07-08 06:59:03 +02:00
|
|
|
;; Kitchen sink
|
|
|
|
;; Mix and match multiple content types to create the card you need, or throw
|
|
|
|
;; everything in there. Shown below are image styles, blocks, text styles, and a
|
|
|
|
;; list group—all wrapped in a fixed-width card.
|
|
|
|
|
|
|
|
(defun card-kitchen-sink ()
|
2023-07-11 18:48:32 +02:00
|
|
|
(card (img (:src "..."))
|
2023-07-13 21:57:54 +02:00
|
|
|
(body (card-title "Card title")
|
|
|
|
(card-text "Some quick example text to build on the card title and make up the bulk of the card's content."))
|
|
|
|
(cl-sbt-list-group (:content "An item")
|
|
|
|
(:content "A second item")
|
|
|
|
(:content "A third item"))
|
|
|
|
(body (card-link "Card Link")
|
|
|
|
(card-link "Another Link"))))
|