Component names now reflect filesystem location using / as path separator and : as namespace separator for shared components: ~sx-header → ~layouts/header ~layout-app-body → ~shared:layout/app-body ~blog-admin-dashboard → ~admin/dashboard 209 files, 4,941 replacements across all services. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
154 lines
9.8 KiB
Plaintext
154 lines
9.8 KiB
Plaintext
;; KG card components — Ghost/Koenig-compatible card rendering
|
||
;; Produces same HTML structure as lexical_renderer.py so cards.css works unchanged.
|
||
;; Used by both display pipeline and block editor.
|
||
|
||
;; @css kg-card kg-image-card kg-width-wide kg-width-full kg-gallery-card kg-gallery-container kg-gallery-row kg-gallery-image kg-embed-card kg-bookmark-card kg-bookmark-container kg-bookmark-content kg-bookmark-title kg-bookmark-description kg-bookmark-metadata kg-bookmark-icon kg-bookmark-author kg-bookmark-publisher kg-bookmark-thumbnail kg-callout-card kg-callout-emoji kg-callout-text kg-button-card kg-btn kg-btn-accent kg-toggle-card kg-toggle-heading kg-toggle-heading-text kg-toggle-card-icon kg-toggle-content kg-audio-card kg-audio-thumbnail kg-audio-player-container kg-audio-title kg-audio-player kg-audio-play-icon kg-audio-current-time kg-audio-time kg-audio-seek-slider kg-audio-playback-rate kg-audio-unmute-icon kg-audio-volume-slider kg-video-card kg-video-container kg-file-card kg-file-card-container kg-file-card-contents kg-file-card-title kg-file-card-filesize kg-file-card-icon kg-file-card-caption kg-align-center kg-align-left kg-callout-card-grey kg-callout-card-white kg-callout-card-blue kg-callout-card-green kg-callout-card-yellow kg-callout-card-red kg-callout-card-pink kg-callout-card-purple kg-callout-card-accent kg-html-card kg-md-card placeholder
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Image card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-image (&key (src :as string) (alt :as string?) (caption :as string?) (width :as string?) (href :as string?))
|
||
(figure :class (str "kg-card kg-image-card"
|
||
(if (= width "wide") " kg-width-wide"
|
||
(if (= width "full") " kg-width-full" "")))
|
||
(if href
|
||
(a :href href (img :src src :alt (or alt "") :loading "lazy"))
|
||
(img :src src :alt (or alt "") :loading "lazy"))
|
||
(when caption (figcaption caption))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Gallery card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-gallery (&key (images :as list) (caption :as string?))
|
||
(figure :class "kg-card kg-gallery-card kg-width-wide"
|
||
(div :class "kg-gallery-container"
|
||
(map (lambda (row)
|
||
(div :class "kg-gallery-row"
|
||
(map (lambda (img-data)
|
||
(figure :class "kg-gallery-image"
|
||
(img :src (get img-data "src") :alt (or (get img-data "alt") "") :loading "lazy")
|
||
(when (get img-data "caption") (figcaption (get img-data "caption")))))
|
||
row)))
|
||
images))
|
||
(when caption (figcaption caption))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; HTML card — wraps user-pasted HTML so the editor can identify the block.
|
||
;; Content is native sx children (no longer an opaque HTML string).
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-html (&rest children)
|
||
(div :class "kg-card kg-html-card" children))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Markdown card — rendered markdown content, editor can identify the block.
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-md (&rest children)
|
||
(div :class "kg-card kg-md-card" children))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Embed card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-embed (&key (html :as string) (caption :as string?))
|
||
(figure :class "kg-card kg-embed-card"
|
||
(~rich-text :html html)
|
||
(when caption (figcaption caption))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Bookmark card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-bookmark (&key (url :as string) (title :as string?) (description :as string?) (icon :as string?) (author :as string?) (publisher :as string?) (thumbnail :as string?) (caption :as string?))
|
||
(figure :class "kg-card kg-bookmark-card"
|
||
(a :class "kg-bookmark-container" :href url
|
||
(div :class "kg-bookmark-content"
|
||
(div :class "kg-bookmark-title" (or title ""))
|
||
(div :class "kg-bookmark-description" (or description ""))
|
||
(when (or icon author publisher)
|
||
(span :class "kg-bookmark-metadata"
|
||
(when icon (img :class "kg-bookmark-icon" :src icon :alt ""))
|
||
(when author (span :class "kg-bookmark-author" author))
|
||
(when publisher (span :class "kg-bookmark-publisher" publisher)))))
|
||
(when thumbnail
|
||
(div :class "kg-bookmark-thumbnail"
|
||
(img :src thumbnail :alt ""))))
|
||
(when caption (figcaption caption))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Callout card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-callout (&key (color :as string?) (emoji :as string?) (content :as string?))
|
||
(div :class (str "kg-card kg-callout-card kg-callout-card-" (or color "grey"))
|
||
(when emoji (div :class "kg-callout-emoji" emoji))
|
||
(div :class "kg-callout-text" (or content ""))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Button card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-button (&key (url :as string) (text :as string?) (alignment :as string?))
|
||
(div :class (str "kg-card kg-button-card kg-align-" (or alignment "center"))
|
||
(a :href url :class "kg-btn kg-btn-accent" (or text ""))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Toggle card (accordion)
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-toggle (&key (heading :as string?) (content :as string?))
|
||
(div :class "kg-card kg-toggle-card" :data-kg-toggle-state "close"
|
||
(div :class "kg-toggle-heading"
|
||
(h4 :class "kg-toggle-heading-text" (or heading ""))
|
||
(button :class "kg-toggle-card-icon"
|
||
(~rich-text :html "<svg viewBox=\"0 0 14 14\"><path d=\"M7 0a.5.5 0 0 1 .5.5v6h6a.5.5 0 1 1 0 1h-6v6a.5.5 0 1 1-1 0v-6h-6a.5.5 0 0 1 0-1h6v-6A.5.5 0 0 1 7 0Z\" fill=\"currentColor\"/></svg>")))
|
||
(div :class "kg-toggle-content" (or content ""))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Audio card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-audio (&key (src :as string) (title :as string?) (duration :as string?) (thumbnail :as string?))
|
||
(div :class "kg-card kg-audio-card"
|
||
(if thumbnail
|
||
(img :src thumbnail :alt "audio-thumbnail" :class "kg-audio-thumbnail")
|
||
(div :class "kg-audio-thumbnail placeholder"
|
||
(~rich-text :html "<svg viewBox=\"0 0 24 24\"><path d=\"M2 12C2 6.48 6.48 2 12 2s10 4.48 10 10-4.48 10-10 10S2 17.52 2 12zm7.5 5.25L16 12 9.5 6.75v10.5z\" fill=\"currentColor\"/></svg>")))
|
||
(div :class "kg-audio-player-container"
|
||
(div :class "kg-audio-title" (or title ""))
|
||
(div :class "kg-audio-player"
|
||
(button :class "kg-audio-play-icon"
|
||
(~rich-text :html "<svg viewBox=\"0 0 24 24\"><path d=\"M8 5v14l11-7z\" fill=\"currentColor\"/></svg>"))
|
||
(div :class "kg-audio-current-time" "0:00")
|
||
(div :class "kg-audio-time" (str "/ " (or duration "0:00")))
|
||
(input :type "range" :class "kg-audio-seek-slider" :max "100" :value "0")
|
||
(button :class "kg-audio-playback-rate" "1×")
|
||
(button :class "kg-audio-unmute-icon"
|
||
(~rich-text :html "<svg viewBox=\"0 0 24 24\"><path d=\"M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z\" fill=\"currentColor\"/></svg>"))
|
||
(input :type "range" :class "kg-audio-volume-slider" :max "100" :value "100")))
|
||
(audio :src src :preload "metadata")))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Video card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-video (&key (src :as string) (caption :as string?) (width :as string?) (thumbnail :as string?) (loop :as boolean?))
|
||
(figure :class (str "kg-card kg-video-card"
|
||
(if (= width "wide") " kg-width-wide"
|
||
(if (= width "full") " kg-width-full" "")))
|
||
(div :class "kg-video-container"
|
||
(video :src src :controls true :preload "metadata"
|
||
:poster (or thumbnail nil) :loop (or loop nil)))
|
||
(when caption (figcaption caption))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; File card
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-file (&key (src :as string) (filename :as string?) (title :as string?) (filesize :as string?) (caption :as string?))
|
||
(div :class "kg-card kg-file-card"
|
||
(a :class "kg-file-card-container" :href src :download (or filename "")
|
||
(div :class "kg-file-card-contents"
|
||
(div :class "kg-file-card-title" (or title filename ""))
|
||
(when filesize (div :class "kg-file-card-filesize" filesize)))
|
||
(div :class "kg-file-card-icon"
|
||
(~rich-text :html "<svg viewBox=\"0 0 24 24\"><path d=\"M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z\" fill=\"currentColor\"/></svg>")))
|
||
(when caption (div :class "kg-file-card-caption" caption))))
|
||
|
||
;; ---------------------------------------------------------------------------
|
||
;; Paywall marker
|
||
;; ---------------------------------------------------------------------------
|
||
(defcomp ~kg_cards/kg-paywall ()
|
||
(~rich-text :html "<!--members-only-->"))
|