Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
227
rich-card.ts12.2 kB
import { defineSlotRecipe } from "@pandacss/dev"; export const richCard = defineSlotRecipe({ className: "rich-card", slots: [ "container", "root", "headerContainer", "menuContainer", "titleContainer", "contentContainer", "mediaContainer", "footerContainer", "mediaBackdropContainer", "mediaBackdrop", "textArea", "text", "media", "mediaMissing", ], base: { container: { containerType: "inline-size", width: "full", }, root: { "--card-border-radius": "radii.lg", "--card-backdrop-index": "1", "--card-media-index": "2", "--card-content-index": "4", position: "relative", display: "grid", width: "full", height: "full", minWidth: "0", minHeight: "0", gap: "0", overflow: "hidden", borderRadius: "var(--card-border-radius)", boxShadow: "sm", backgroundColor: "bg.default", }, headerContainer: { minWidth: "0", minHeight: "0", }, menuContainer: { display: "flex", flexDirection: "column", }, titleContainer: { lineClamp: "1", fontWeight: "bold", }, contentContainer: { display: "flex", flexDirection: "column", justifyContent: "space-between", gap: "2", height: "full", minWidth: "0", overflow: "hidden", }, mediaContainer: { contain: "size", }, footerContainer: { display: "flex", justifyContent: "start", width: "full", minWidth: "0", gap: "2", }, mediaBackdropContainer: { contain: "size", pointerEvents: "none", }, // mediaBackdrop: { width: "full", height: "full", objectPosition: "center", objectFit: "cover", blur: "xl", filter: "auto", opacity: "0.1", }, media: { width: "full", height: "full", objectFit: "cover", // This fixes pixelated images in Chrome... for some reason? overflowClipMargin: "unset", }, textArea: { mb: "2", }, text: { lineClamp: "1", }, }, variants: { shape: { row: { root: { gridTemplateColumns: `[edge-start] 0.5rem [content-start] 1fr [content-end] 0.5rem [media-start] minmax(0, 25cqw) [media-end] 0.5rem [edge-end]`, gridTemplateRows: `[edge-start] 0.5rem [header-start] min-content [header-end] 0 [title-start] min-content [title-end] 0 [content-start] 1fr [content-end] 0 [footer-start] min-content [footer-end] 0.5rem [edge-end]`, }, container: { width: "full", }, // - // Container slots. // - headerContainer: { gridColumn: "content-start / content-end", gridRow: "header-start / header-end", }, menuContainer: { gridColumn: "media-start / media-end", gridRow: "header-start / header-end", alignSelf: "start", justifySelf: "end", }, titleContainer: { gridColumn: "content-start / content-end", gridRow: "title-start / title-end", }, contentContainer: { gridColumn: "content-start / content-start", gridRow: "content-start / content-end", height: "min", }, mediaContainer: { gridColumn: "media-start / edge-end", gridRow: "edge-start / edge-end", // SEE: comment on aspectRatio in "responsive" variant. // aspectRatio: "1.777", minHeight: "0", }, footerContainer: { gridColumn: "content-start / media-end", gridRow: "footer-start / footer-end", gap: "2", }, mediaBackdropContainer: { gridColumn: "edge-start / edge-end", gridRow: "edge-start / edge-end", background: "backgroundGradientH", }, // - // Non-container slots. // - mediaMissing: { display: "none", }, mediaBackdrop: { // This blends the backdrop image horizontally so the backdrop doesn't // cover the entire row and potentially make it too attention-seeking. maskImage: "linear-gradient(90deg, transparent 0%, white 40%, white 100%)", }, }, responsive: { root: { gridTemplateColumns: `[edge-start] 0.5rem [content-start] 1fr [content-end] 0.5rem [media-start] minmax(0, 25cqw) [media-end] 0.5rem [edge-end]`, gridTemplateRows: `[edge-start] 0.5rem [header-start] min-content [header-end] 0 [title-start] min-content [title-end] 0 [content-start] 1fr [content-end] 0 [footer-start] min-content [footer-end] 0.5rem [edge-end]`, _containerSmall: { gridTemplateColumns: `[edge-start] 0.5rem [content-start] 1fr [content-end] 0.5rem [edge-end]`, gridTemplateRows: `[edge-start] 0.5rem [header-start] min-content [header-end] 0 [title-start] min-content [title-end] 0 [content-start] 1fr [content-end] 0 [media-start] auto [media-end] 0 [footer-start] min-content [footer-end] 0.5rem [edge-end]`, }, }, // - // Container slots. // - headerContainer: { gridColumn: "content-start / content-end", gridRow: "header-start / header-end", }, menuContainer: { gridColumn: "media-start / media-end", gridRow: "header-start / header-end", alignSelf: "start", justifySelf: "end", }, titleContainer: { gridColumn: "content-start / content-end", gridRow: "title-start / title-end", }, contentContainer: { gridColumn: "content-start / content-start", gridRow: "content-start / content-end", height: "min", }, mediaContainer: { gridColumn: "media-start / edge-end", gridRow: "edge-start / edge-end", _containerSmall: { gridColumn: "content-start / content-end", gridRow: "media-start / media-end", minHeight: "64", marginBottom: "2", aspectRatio: "auto", height: "unset", }, // NOTE: A firefox bug prevents us from doing this. Because the grid // track for the media container cannot be auto in Firefox, it must be // a fixed width. If it's a fixed width (25cqw in this case), then the // aspect ratio forces a height to be contributed to the parent's size // calculations which we do not want as it makes the card taller than // the text content. Ultimately, we want the text content to be the // only contribution to the height calculations. It's unclear why the // contain: size does not fix this in Firefox like it does in Chrome. // aspectRatio: "1.777", minHeight: "0", height: "full", }, footerContainer: { gridColumn: "content-start / media-end", _containerSmall: { gridColumn: "content-start / content-end", }, gridRow: "footer-start / footer-end", gap: "2", }, mediaBackdropContainer: { gridColumn: "edge-start / edge-end", gridRow: "edge-start / edge-end", background: "backgroundGradientH", }, // - // Non-container slots. // - media: { _containerSmall: { borderRadius: "sm", }, }, mediaMissing: { display: "none", }, text: {}, }, box: { root: { gridTemplateColumns: `[edge-start] 0.5rem [content-start] 1fr [content-end] 0.5rem [edge-end]`, gridTemplateRows: `[edge-start] 0.5rem min-content min-content auto auto min-content 0.5rem [edge-end]`, gridTemplateAreas: ` ". . . " ". header . " ". title . " ". content . " ". media . " ". footer . " ". . . " `, }, // - // Container slots. // - headerContainer: { gridColumn: "content-start / content-end", gridRow: "header-start / header-end", }, menuContainer: { gridColumn: "media-start / media-end", gridRow: "header-start / header-end", alignSelf: "start", justifySelf: "end", }, titleContainer: { gridColumn: "content-start / content-end", gridRow: "title-start / title-end", }, contentContainer: { gridArea: "content", }, mediaContainer: { gridArea: "media", marginBottom: "2", minHeight: "64", }, footerContainer: { gridArea: "footer", gap: "2", }, mediaBackdropContainer: { gridRow: "edge-start / edge-end", gridColumn: "edge-start / edge-end", }, // - // Non-container slots. // - media: { objectPosition: "center", borderRadius: "sm", }, mediaMissing: { gridRow: "1 / 2", gridColumn: "1 / 2", height: "full", // NOTE: This padding is to center the Empty component. It's not // really perfect but close enough! It's a bit of a hack. paddingBottom: "3lh", }, text: { _containerSmall: { display: "none", }, }, }, fill: { root: { gridTemplateColumns: `[edge-start] 0.5rem [content-start] 1fr [content-end] 0.5rem [edge-end]`, gridTemplateRows: `[edge-start] 0.5rem [header-start] min-content [header-end] 300px [content-start] min-content [footer-start] min-content [edge-end]`, }, // - // Container slots. // - headerContainer: { gridColumn: "content-start / content-end", gridRow: "header-start / header-end", borderRadius: "sm", padding: "1", background: "bg.canvas/60", backdropBlur: "frosted", backdropGrayscale: "0.5", backdropFilter: "auto", }, menuContainer: { // Unused in this variant display: "none", }, titleContainer: { // Unused in this variant display: "none", }, contentContainer: { gridRow: "content-start / footer-start", gridColumn: "edge-start / edge-end", padding: "2", paddingBottom: "0", }, mediaContainer: { gridRow: "edge-start / edge-end", gridColumn: "edge-start / edge-end", minHeight: "64", }, footerContainer: { gridRow: "footer-start / edge-end", gridColumn: "edge-start / edge-end", paddingTop: "0", padding: "2", gap: "2", }, mediaBackdropContainer: { gridRow: "content-start / edge-end", gridColumn: "edge-start / edge-end", background: "bg.canvas/90", backdropBlur: "frosted", backdropGrayscale: "0.5", backdropFilter: "auto", }, mediaBackdrop: { display: "none", }, // - // Non-container slots. // - media: { objectPosition: "top", // NOTE: This solves a small rendering issue on Chrome where the image // ever so slightly overflows the border radius. The cause looks like // it's due to a combination of the overflow hidden and object-fit. borderBottomRadius: "calc(var(--card-border-radius) + 3px)", }, text: { _containerSmall: { display: "none", }, }, }, }, }, compoundVariants: [], defaultVariants: { shape: "row", }, jsx: ["Card", "NodeCard"], });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server