UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

308 lines (307 loc) 6.28 kB
import { i as attachFooterText } from "./schedule-cards-Bq74H30B.js"; //#region extensions/line/src/flex-templates/basic-cards.ts /** * Create an info card with title, body, and optional footer * * Editorial design: Clean hierarchy with accent bar, generous spacing, * and subtle background zones for visual separation. */ function createInfoCard(title, body, footer) { const bubble = { type: "bubble", size: "mega", body: { type: "box", layout: "vertical", contents: [{ type: "box", layout: "horizontal", contents: [{ type: "box", layout: "vertical", contents: [], width: "4px", backgroundColor: "#06C755", cornerRadius: "2px" }, { type: "text", text: title, weight: "bold", size: "xl", color: "#111111", wrap: true, flex: 1, margin: "lg" }] }, { type: "box", layout: "vertical", contents: [{ type: "text", text: body, size: "md", color: "#444444", wrap: true, lineSpacing: "6px" }], margin: "xl", paddingAll: "lg", backgroundColor: "#F8F9FA", cornerRadius: "lg" }], paddingAll: "xl", backgroundColor: "#FFFFFF" } }; if (footer) attachFooterText(bubble, footer); return bubble; } /** * Create a list card with title and multiple items * * Editorial design: Numbered/bulleted list with clear visual hierarchy, * accent dots for each item, and generous spacing. */ function createListCard(title, items) { const itemContents = items.slice(0, 8).map((item, index) => { const itemContentsLocal = [{ type: "text", text: item.title, size: "md", weight: "bold", color: "#1a1a1a", wrap: true }]; if (item.subtitle) itemContentsLocal.push({ type: "text", text: item.subtitle, size: "sm", color: "#888888", wrap: true, margin: "xs" }); const itemBox = { type: "box", layout: "horizontal", contents: [{ type: "box", layout: "vertical", contents: [{ type: "box", layout: "vertical", contents: [], width: "8px", height: "8px", backgroundColor: index === 0 ? "#06C755" : "#DDDDDD", cornerRadius: "4px" }], width: "20px", alignItems: "center", paddingTop: "sm" }, { type: "box", layout: "vertical", contents: itemContentsLocal, flex: 1 }], margin: index > 0 ? "lg" : void 0 }; if (item.action) itemBox.action = item.action; return itemBox; }); return { type: "bubble", size: "mega", body: { type: "box", layout: "vertical", contents: [ { type: "text", text: title, weight: "bold", size: "xl", color: "#111111", wrap: true }, { type: "separator", margin: "lg", color: "#EEEEEE" }, { type: "box", layout: "vertical", contents: itemContents, margin: "lg" } ], paddingAll: "xl", backgroundColor: "#FFFFFF" } }; } /** * Create an image card with image, title, and optional body text */ function createImageCard(imageUrl, title, body, options) { const bubble = { type: "bubble", hero: { type: "image", url: imageUrl, size: "full", aspectRatio: options?.aspectRatio ?? "20:13", aspectMode: options?.aspectMode ?? "cover", action: options?.action }, body: { type: "box", layout: "vertical", contents: [{ type: "text", text: title, weight: "bold", size: "xl", wrap: true }], paddingAll: "lg" } }; if (body && bubble.body) bubble.body.contents.push({ type: "text", text: body, size: "md", wrap: true, margin: "md", color: "#666666" }); return bubble; } /** * Create an action card with title, body, and action buttons */ function createActionCard(title, body, actions, options) { const bubble = { type: "bubble", body: { type: "box", layout: "vertical", contents: [{ type: "text", text: title, weight: "bold", size: "xl", wrap: true }, { type: "text", text: body, size: "md", wrap: true, margin: "md", color: "#666666" }], paddingAll: "lg" }, footer: { type: "box", layout: "vertical", contents: actions.slice(0, 4).map((action, index) => ({ type: "button", action: action.action, style: index === 0 ? "primary" : "secondary", margin: index > 0 ? "sm" : void 0 })), paddingAll: "md" } }; if (options?.imageUrl) bubble.hero = { type: "image", url: options.imageUrl, size: "full", aspectRatio: options.aspectRatio ?? "20:13", aspectMode: "cover" }; return bubble; } /** * Create a carousel container from multiple bubbles * LINE allows max 12 bubbles in a carousel */ function createCarousel(bubbles) { return { type: "carousel", contents: bubbles.slice(0, 12) }; } /** * Create a notification bubble (for alerts, status updates) * * Editorial design: Bold status indicator with accent color, * clear typography, optional icon for context. */ function createNotificationBubble(text, options) { const typeColors = { info: { accent: "#3B82F6", bg: "#EFF6FF" }, success: { accent: "#06C755", bg: "#F0FDF4" }, warning: { accent: "#F59E0B", bg: "#FFFBEB" }, error: { accent: "#EF4444", bg: "#FEF2F2" } }[options?.type ?? "info"]; const contents = []; contents.push({ type: "box", layout: "vertical", contents: [], width: "4px", backgroundColor: typeColors.accent, cornerRadius: "2px" }); const textContents = []; if (options?.title) textContents.push({ type: "text", text: options.title, size: "md", weight: "bold", color: "#111111", wrap: true }); textContents.push({ type: "text", text, size: options?.title ? "sm" : "md", color: options?.title ? "#666666" : "#333333", wrap: true, margin: options?.title ? "sm" : void 0 }); contents.push({ type: "box", layout: "vertical", contents: textContents, flex: 1, paddingStart: "lg" }); return { type: "bubble", body: { type: "box", layout: "horizontal", contents, paddingAll: "xl", backgroundColor: typeColors.bg } }; } //#endregion export { createListCard as a, createInfoCard as i, createCarousel as n, createNotificationBubble as o, createImageCard as r, createActionCard as t };