Examples & Use Cases
Real-world examples and common use cases for Sone
Examples & Use Cases
This page provides comprehensive examples of common use cases for Sone, from simple documents to complex layouts.
Business Documents
Invoice Template
import { Column, Row, Text, Span, Table, TableRow, TableCell, sone } from "sone";
function InvoiceTemplate(invoiceData) {
const { company, client, items, invoiceNumber, date } = invoiceData;
return Column(
// Header
Row(
Column(
Text(company.name).size(24).weight("bold"),
Text(company.address).size(12).color("gray"),
Text(`${company.city}, ${company.state} ${company.zip}`).size(12).color("gray"),
Text(company.phone).size(12).color("gray")
).flex(1),
Column(
Text("INVOICE").size(32).weight("bold").color("#2563eb"),
Text(`#${invoiceNumber}`).size(16).weight("500"),
Text(date).size(14).color("gray")
).alignItems("flex-end")
).marginBottom(40),
// Bill To
Column(
Text("Bill To:").size(14).weight("bold").marginBottom(10),
Text(client.name).size(16).weight("500"),
Text(client.address).size(14).color("gray"),
Text(`${client.city}, ${client.state} ${client.zip}`).size(14).color("gray")
).marginBottom(30),
// Items Table
Table(
// Header
TableRow(
TableCell(Text("Description").weight("bold").size(14)),
TableCell(Text("Qty").weight("bold").size(14).align("center")),
TableCell(Text("Rate").weight("bold").size(14).align("right")),
TableCell(Text("Amount").weight("bold").size(14).align("right"))
)
.bg("#f8fafc")
.borderBottomWidth(2)
.borderColor("#e2e8f0"),
// Items
...items.map(item =>
TableRow(
TableCell(Text(item.description).size(13)),
TableCell(Text(item.quantity.toString()).size(13).align("center")),
TableCell(Text(`$${item.rate.toFixed(2)}`).size(13).align("right")),
TableCell(Text(`$${(item.quantity * item.rate).toFixed(2)}`).size(13).align("right"))
)
.padding(12, 0)
.borderBottomWidth(1)
.borderColor("#e2e8f0")
)
).marginBottom(20),
// Total
Row(
Column().flex(1),
Column(
Row(
Text("Subtotal:").size(14).weight("500"),
Text(`$${items.reduce((sum, item) => sum + (item.quantity * item.rate), 0).toFixed(2)}`)
.size(14).marginLeft(40)
).marginBottom(8),
Row(
Text("Tax (10%):").size(14).weight("500"),
Text(`$${(items.reduce((sum, item) => sum + (item.quantity * item.rate), 0) * 0.1).toFixed(2)}`)
.size(14).marginLeft(40)
).marginBottom(8),
Row(
Text("Total:").size(16).weight("bold").color("#2563eb"),
Text(`$${(items.reduce((sum, item) => sum + (item.quantity * item.rate), 0) * 1.1).toFixed(2)}`)
.size(16).weight("bold").color("#2563eb").marginLeft(40)
)
.padding(12, 0)
.borderTopWidth(2)
.borderColor("#2563eb")
).width(200)
)
)
.padding(40)
.bg("white")
.maxWidth(800);
}
// Usage
const invoice = await sone(InvoiceTemplate({
company: {
name: "Acme Corp",
address: "123 Business St",
city: "Business City",
state: "BC",
zip: "12345",
phone: "(555) 123-4567"
},
client: {
name: "John Smith",
address: "456 Client Ave",
city: "Client City",
state: "CC",
zip: "67890"
},
invoiceNumber: "INV-2024-001",
date: "January 15, 2024",
items: [
{ description: "Web Development", quantity: 40, rate: 100 },
{ description: "Design Services", quantity: 20, rate: 80 }
]
})).pdf();
Certificate Template
function CertificateTemplate(recipient, course, date, instructor) {
return Column(
// Decorative border
Column(
// Header
Text("CERTIFICATE OF COMPLETION")
.size(36)
.weight("bold")
.color("#1f2937")
.align("center")
.letterSpacing(4)
.marginBottom(40),
// Decorative line
Row()
.height(3)
.width(300)
.bg("linear-gradient(90deg, #f59e0b, #d97706)")
.rounded(2)
.margin("auto")
.marginBottom(40),
// Content
Text("This is to certify that")
.size(18)
.color("#6b7280")
.align("center")
.marginBottom(20),
Text(recipient)
.size(42)
.weight("bold")
.color("#1f2937")
.align("center")
.marginBottom(30)
.borderBottomWidth(2)
.borderColor("#e5e7eb")
.paddingBottom(10),
Text("has successfully completed the course")
.size(18)
.color("#6b7280")
.align("center")
.marginBottom(20),
Text(course)
.size(28)
.weight("600")
.color("#059669")
.align("center")
.marginBottom(40),
Text(`on ${date}`)
.size(16)
.color("#6b7280")
.align("center")
.marginBottom(60),
// Signature section
Row(
Column(
Row()
.height(2)
.width(200)
.bg("#9ca3af")
.marginBottom(8),
Text(instructor)
.size(16)
.weight("500")
.align("center"),
Text("Instructor")
.size(12)
.color("#6b7280")
.align("center")
)
).justifyContent("center")
)
.padding(80)
.bg("white")
)
.size(800, 600)
.bg("linear-gradient(135deg, #fef3c7, #fde68a)")
.shadow("0 20px 40px rgba(0,0,0,0.1)")
.rounded(20)
.borderWidth(8)
.borderColor("#f59e0b")
.justifyContent("center")
.alignItems("center");
}
Marketing Materials
Social Media Post
function SocialMediaPost(content, author, image) {
return Column(
// Background image overlay
Column(
Column(
Text(content.title)
.size(32)
.weight("bold")
.color("white")
.align("center")
.dropShadow("2px 2px 8px rgba(0,0,0,0.8)")
.marginBottom(15),
Text(content.subtitle)
.size(18)
.color("white")
.align("center")
.dropShadow("1px 1px 4px rgba(0,0,0,0.8)")
.opacity(0.9)
)
.padding(40)
.bg("linear-gradient(135deg, rgba(99, 102, 241, 0.8), rgba(139, 92, 246, 0.8))")
.rounded(20)
.shadow("0 10px 20px rgba(0,0,0,0.3)")
)
.justifyContent("center")
.alignItems("center")
.size(600, 400)
.bg(Photo(image))
.rounded(15)
)
.shadow("0 20px 40px rgba(0,0,0,0.2)");
}
Business Card
function BusinessCard(person) {
return Row(
// Left side - Contact info
Column(
Text(person.name)
.size(24)
.weight("bold")
.color("#1f2937")
.marginBottom(5),
Text(person.title)
.size(14)
.color("#6366f1")
.weight("500")
.marginBottom(20),
Column(
Text(person.email).size(12).color("#4b5563"),
Text(person.phone).size(12).color("#4b5563"),
Text(person.website).size(12).color("#4b5563")
).gap(5)
)
.flex(1)
.padding(25),
// Right side - Logo/Brand
Column(
Text(person.company)
.size(20)
.weight("bold")
.color("#6366f1")
.align("right")
)
.flex(1)
.padding(25)
.bg("linear-gradient(135deg, #f8fafc, #e2e8f0)")
.justifyContent("center")
)
.size(350, 200)
.bg("white")
.rounded(12)
.shadow("0 4px 12px rgba(0,0,0,0.15)")
.borderWidth(1)
.borderColor("#e5e7eb");
}
Data Visualization
Report Dashboard
function ReportDashboard(data) {
return Column(
// Header
Row(
Text("Monthly Report")
.size(28)
.weight("bold")
.color("#1f2937"),
Text(data.period)
.size(16)
.color("#6b7280")
)
.justifyContent("space-between")
.alignItems("center")
.marginBottom(30),
// KPI Cards
Row(
...data.kpis.map(kpi =>
Column(
Text(kpi.value)
.size(32)
.weight("bold")
.color(kpi.trend > 0 ? "#059669" : kpi.trend < 0 ? "#dc2626" : "#1f2937")
.align("center"),
Text(kpi.label)
.size(14)
.color("#6b7280")
.align("center")
.marginTop(8),
Text(`${kpi.trend > 0 ? '+' : ''}${kpi.trend}%`)
.size(12)
.weight("500")
.color(kpi.trend > 0 ? "#059669" : kpi.trend < 0 ? "#dc2626" : "#6b7280")
.align("center")
.marginTop(4)
)
.flex(1)
.padding(20)
.bg("white")
.rounded(8)
.shadow("0 1px 3px rgba(0,0,0,0.1)")
.margin(0, 10)
)
).marginBottom(30),
// Data Table
Table(
// Header
TableRow(
...data.tableHeaders.map(header =>
TableCell(Text(header).weight("bold").size(14))
.padding(12)
.bg("#f9fafb")
)
),
// Rows
...data.tableData.map((row, index) =>
TableRow(
...row.map(cell =>
TableCell(Text(cell.toString()).size(13))
.padding(12)
)
)
.bg(index % 2 === 0 ? "white" : "#f9fafb")
)
)
.borderWidth(1)
.borderColor("#d1d5db")
.rounded(6)
)
.padding(40)
.bg("#f3f4f6")
.minHeight(800);
}
Performance Chart Placeholder
function ChartPlaceholder(title, data) {
return Column(
Text(title)
.size(16)
.weight("600")
.color("#374151")
.marginBottom(15),
// Simulated bar chart
Row(
...data.map((value, index) =>
Column(
Column()
.width(30)
.height(value * 2) // Scale height
.bg(`hsl(${200 + index * 30}, 70%, 50%)`)
.rounded(4, 4, 0, 0),
Text(value.toString())
.size(10)
.align("center")
.marginTop(5)
)
.alignItems("center")
.margin(0, 2)
)
)
.alignItems("flex-end")
.justifyContent("center")
.height(200)
)
.padding(20)
.bg("white")
.rounded(8)
.shadow("0 1px 3px rgba(0,0,0,0.1)");
}
Educational Content
Resume Template
function ResumeTemplate(resume) {
return Column(
// Header
Column(
Text(resume.name)
.size(32)
.weight("bold")
.color("#1f2937")
.align("center"),
Text(resume.title)
.size(18)
.color("#6366f1")
.align("center")
.marginTop(8),
Row(
Text(resume.email).size(12),
Text(resume.phone).size(12),
Text(resume.location).size(12)
)
.gap(20)
.justifyContent("center")
.marginTop(15)
.color("#6b7280")
)
.marginBottom(30)
.borderBottomWidth(2)
.borderColor("#e5e7eb")
.paddingBottom(20),
// Experience Section
Column(
Text("Experience")
.size(20)
.weight("bold")
.color("#1f2937")
.marginBottom(15),
...resume.experience.map(job =>
Column(
Row(
Text(job.title).size(16).weight("600"),
Text(job.period).size(14).color("#6b7280")
)
.justifyContent("space-between")
.alignItems("center"),
Text(job.company)
.size(14)
.color("#6366f1")
.marginTop(2),
Text(job.description)
.size(12)
.color("#4b5563")
.lineHeight(1.5)
.marginTop(8)
)
.marginBottom(20)
)
)
.marginBottom(25),
// Skills Section
Column(
Text("Skills")
.size(20)
.weight("bold")
.color("#1f2937")
.marginBottom(15),
Row(
...resume.skills.map(skill =>
Text(skill)
.size(12)
.color("#1f2937")
.bg("#f3f4f6")
.padding(6, 12)
.rounded(20)
)
)
.gap(10)
.wrap("wrap")
)
)
.padding(40)
.bg("white")
.maxWidth(600);
}
Course Materials
function CoursePage(lesson) {
return Column(
// Header
Column(
Text(lesson.title)
.size(28)
.weight("bold")
.color("#1f2937")
.marginBottom(10),
Row(
Text(`Lesson ${lesson.number}`).size(14).color("#6366f1"),
Text(`Duration: ${lesson.duration}`).size(14).color("#6b7280")
)
.gap(20)
)
.marginBottom(30),
// Objectives
Column(
Text("Learning Objectives")
.size(18)
.weight("600")
.color("#1f2937")
.marginBottom(15),
...lesson.objectives.map((objective, index) =>
Row(
Text(`${index + 1}.`).size(14).weight("500").width(30),
Text(objective).size(14).flex(1)
)
.marginBottom(8)
.color("#374151")
)
)
.marginBottom(30),
// Content
Column(
...lesson.content.map(section =>
Column(
Text(section.heading)
.size(16)
.weight("600")
.color("#1f2937")
.marginBottom(10),
Text(section.text)
.size(14)
.lineHeight(1.6)
.color("#374151")
.marginBottom(20)
)
)
)
)
.padding(40)
.bg("white")
.maxWidth(700);
}
Creative Layouts
Magazine Layout
function MagazineArticle(article) {
return Column(
// Hero section
Column(
Text(article.title)
.size(36)
.weight("bold")
.color("white")
.align("center")
.dropShadow("2px 2px 8px rgba(0,0,0,0.8)"),
Text(article.subtitle)
.size(18)
.color("white")
.align("center")
.opacity(0.9)
.marginTop(15)
)
.justifyContent("center")
.alignItems("center")
.size(800, 400)
.bg(Photo(article.heroImage))
.marginBottom(40),
// Article content
Column(
Row(
// Main content
Column(
Text(article.content)
.size(16)
.lineHeight(1.7)
.color("#374151")
.align("justify")
)
.flex(2)
.marginRight(40),
// Sidebar
Column(
Text("Related Articles")
.size(18)
.weight("bold")
.marginBottom(20),
...article.related.map(related =>
Column(
Text(related.title)
.size(14)
.weight("600")
.color("#1f2937")
.marginBottom(5),
Text(related.excerpt)
.size(12)
.color("#6b7280")
.lineHeight(1.5)
)
.padding(15)
.bg("#f9fafb")
.rounded(8)
.marginBottom(15)
)
)
.flex(1)
)
)
.padding(0, 40)
)
.bg("white");
}
Event Poster
function EventPoster(event) {
return Column(
// Background with gradient overlay
Column(
Text(event.name)
.size(42)
.weight("bold")
.color("white")
.align("center")
.dropShadow("3px 3px 12px rgba(0,0,0,0.8)")
.marginBottom(20),
Text(event.tagline)
.size(20)
.color("white")
.align("center")
.style("italic")
.opacity(0.9)
.marginBottom(40),
Column(
Text(event.date)
.size(24)
.weight("600")
.color("#fbbf24")
.align("center"),
Text(event.time)
.size(18)
.color("white")
.align("center")
.marginTop(8),
Text(event.location)
.size(16)
.color("white")
.align("center")
.marginTop(8)
)
.padding(30)
.bg("rgba(0,0,0,0.6)")
.rounded(15)
.marginBottom(30),
Text("REGISTER NOW")
.size(18)
.weight("bold")
.color("black")
.bg("#fbbf24")
.padding(15, 40)
.rounded(25)
.shadow("0 4px 12px rgba(251, 191, 36, 0.4)")
)
.justifyContent("center")
.alignItems("center")
.size(600, 800)
.bg("linear-gradient(135deg, rgba(99, 102, 241, 0.8), rgba(139, 92, 246, 0.8))")
)
.shadow("0 20px 40px rgba(0,0,0,0.3)")
.rounded(20);
}
Export Examples
Multi-page Document
async function generateReport(data) {
// Page 1: Cover
const coverPage = Column(
Text("Annual Report 2024")
.size(48)
.weight("bold")
.color("#1f2937")
.align("center"),
Text("Company Performance Overview")
.size(24)
.color("#6b7280")
.align("center")
.marginTop(20)
)
.justifyContent("center")
.alignItems("center")
.size(800, 600)
.bg("white");
// Page 2: Summary
const summaryPage = ReportDashboard(data);
// Export as PDF
const coverPdf = await sone(coverPage).pdf();
const summaryPdf = await sone(summaryPage).pdf();
return { coverPdf, summaryPdf };
}
Social Media Variants
async function generateSocialVariants(content) {
// Instagram Square
const instagram = SocialMediaPost(content, null, content.image)
.size(1080, 1080);
// Twitter Card
const twitter = SocialMediaPost(content, null, content.image)
.size(1200, 628);
// Facebook Cover
const facebook = SocialMediaPost(content, null, content.image)
.size(1200, 630);
return {
instagram: await sone(instagram).jpg(),
twitter: await sone(twitter).jpg(),
facebook: await sone(facebook).jpg()
};
}
These examples demonstrate the versatility of Sone for creating professional documents, marketing materials, data visualizations, and creative layouts. Each example can be customized and extended based on specific needs.