Complete technical reference for the RSL JSON Layout system
The RSL JSON Layout system provides declarative, JSON-driven layout rendering with two API versions:
Use V2 for new projects. V1 is fully supported for backward compatibility.
<!-- Include required files -->
<link rel="stylesheet" href="styles/grid.css">
<link rel="stylesheet" href="styles/cards.css">
<script src="javascript/layout.js"></script>
<script src="javascript/layout-json-engine-v2.js"></script>
<div id="app"></div>
<script>
RSL.JSONLayout.renderLayout('#app', {
version: 2,
layoutId: "my-layout",
breakpoints: { xs: 1, md: 2, lg: 3 },
gap: "1.5rem",
items: [
{
content: {
type: "card",
title: "Welcome",
body: "This is a semantic card component.",
button: { text: "Learn More", variant: "primary" }
}
}
]
});
</script>
| Type | Description |
|---|---|
card | Card component with title, body, image, buttons |
grid | Nested grid layout |
balanced | Masonry-style balanced layout |
divider | Horizontal divider line |
spacer | Vertical spacing |
| Type | Description |
|---|---|
heading | H1-H6 headings with level option |
paragraph | Text paragraph |
text | Plain text content |
list | Ordered or unordered lists |
badge | Inline badge/tag |
| Type | Description |
|---|---|
button | Button with variants and icons |
link | Hyperlink |
accordion | Expandable accordion panels |
tabs | Tabbed content interface |
modal | Modal dialog |
select | Dropdown select |
tooltip | Tooltip on hover |
popover | Popover panel |
toast | Toast notification |
| Type | Description |
|---|---|
image | Image with alt text |
thumbnail | Image card with overlay |
gallery | Image gallery with lightbox |
carousel | Image slideshow |
video-player | Video player component |
iframe | Embedded iframe |
icon | FontAwesome icon |
| Type | Description |
|---|---|
navbar | Navigation bar |
breadcrumb | Breadcrumb navigation |
pagination | Page navigation |
sidebar | Sidebar layout |
offcanvas | Slide-out panel |
| Type | Description |
|---|---|
table | Data table |
smart-table | Advanced table with sorting/filtering |
chart | SVG charts (bar, line, pie, etc.) |
kpi | KPI dashboard cards |
gantt | Gantt chart |
progress | Progress bar |
calendar | Full calendar component |
| Type | Description |
|---|---|
form | Form container |
datepicker | Date picker |
timepicker | Time picker |
filter | Filter controls |
star-rating | Star rating input |
| Type | Description |
|---|---|
alert | Alert message |
inlayAlert | Inline contextual alert |
skeleton | Loading placeholder |
announcements | Announcement bar |
| Type | Description |
|---|---|
hero | Hero section |
testimonial | Testimonial card |
pricing-table | Pricing comparison |
iconpicker | Icon selection |
| Type | Description |
|---|---|
html | Raw HTML content |
slot | Template slot reference |
component | RSL component reference |
The template system renders arrays of data with {{variable}} interpolation.
const products = [
{ name: "Product 1", price: "99", image: "img1.jpg" },
{ name: "Product 2", price: "149", image: "img2.jpg" },
{ name: "Product 3", price: "199", image: "img3.jpg" }
];
RSL.JSONLayout.renderLayout('#container', {
version: 2,
layoutId: "products",
breakpoints: { xs: 1, md: 2, lg: 3 },
template: {
data: products,
item: {
content: {
type: "card",
image: "{{image}}",
title: "{{name}}",
price: "${{price}}",
button: { text: "Buy Now", variant: "primary" }
}
}
}
});
{{key}} - Replace with data[key]{{index}} - Current item index (0-based){{index1}} - Current item index (1-based)Interpolation works on any string value, including nested properties and classes.
Renders a layout from JSON configuration.
HTMLElement - The created layout element
Converts existing HTML to JSON configuration.
Object - JSON configuration
// From HTML string
const config = RSL.JSONLayout.convertHTMLtoJSON('<div class="slot-layout">...</div>');
// From selector
const config = RSL.JSONLayout.convertHTMLtoJSON('#my-container');
// From element
const config = RSL.JSONLayout.convertHTMLtoJSON(document.body);
Validates a JSON layout configuration.
Object - { valid: boolean, errors: string[], warnings: string[] }
Updates an existing layout (diff-based, preserves DOM where possible).
Object - { added, updated, removed } stats
{
version: 2, // Schema version (required)
layoutId: string, // Unique ID (required)
breakpoints: { // Column counts per breakpoint
xs?: number, // Extra small (<480px)
sm?: number, // Small (>=480px)
md?: number, // Medium (>=768px)
lg?: number, // Large (>=1024px)
xl?: number, // Extra large (>=1280px)
xxl?: number // Extra extra large (>=1600px)
},
gap?: string, // Gap between items (e.g., "1.5rem")
pageMode?: boolean, // Full page rendering mode
items?: LayoutItem[], // Array of layout items
template?: { // Template system config
data: any[], // Array of data objects
item: LayoutItem // Template for each item
}
}
{
id?: string, // Unique ID
classes?: string[], // CSS classes
order?: number, // Flex order
visible?: boolean, // Visibility (default: true)
span?: { // Column span per breakpoint
xs?: number,
sm?: number,
md?: number,
lg?: number
},
content?: ContentConfig, // Item content
style?: Record<string, string>, // Inline styles
data?: Record<string, string> // Data attributes
}
{
type: "card",
image: "photo.jpg",
imageAlt: "Description",
title: "Card Title",
titleIcon: "fa fa-star", // Icon before title
subtitle: "Subtitle text",
body: "Card body content",
price: "$99",
button: { text: "Action", variant: "primary", href: "#" },
buttons: [ // Multiple buttons
{ text: "Primary", variant: "primary" },
{ text: "Secondary", variant: "secondary" }
]
}
{
type: "accordion",
variant: "classic", // "classic" or "modern"
allowMultiple: false,
items: [
{ title: "Section 1", content: "Content 1", open: true },
{ title: "Section 2", content: "Content 2" }
]
}
{
type: "tabs",
variant: "horizontal", // "horizontal" or "vertical"
tabs: [
{ id: "tab1", label: "Tab 1", content: "Content 1", active: true },
{ id: "tab2", label: "Tab 2", content: "Content 2" }
]
}
{
type: "table",
headers: ["Name", "Email", "Role"],
rows: [
["John Doe", "john@example.com", "Admin"],
["Jane Smith", "jane@example.com", "User"]
],
striped: true,
hoverable: true
}
{
type: "chart",
chartType: "bar", // bar, line, area, pie, doughnut
data: [
{ label: "Jan", value: 100 },
{ label: "Feb", value: 150 },
{ label: "Mar", value: 120 }
],
colorScheme: "primary",
showLegend: true,
showGrid: true
}
{
type: "gallery",
images: [
{ src: "img1.jpg", alt: "Image 1", caption: "Caption 1" },
{ src: "img2.jpg", alt: "Image 2", caption: "Caption 2" }
],
columns: { xs: 2, md: 3, lg: 4 },
gap: "1rem",
lightbox: true
}
{
type: "hero",
title: "Welcome",
subtitle: "Build amazing layouts",
backgroundImage: "hero.jpg",
buttons: [
{ text: "Get Started", variant: "primary" },
{ text: "Learn More", variant: "secondary" }
],
centered: true
}
{
type: "html",
value: "<div class='custom-widget'><h3>Custom Content</h3><p>Any HTML here</p></div>"
}
For undo/redo and preset management, include the state manager:
<script src="javascript/layout-state-manager.js"></script>
<script src="javascript/layout-control-panel.js"></script>
// Save state to history
RSL.StateManager.pushToHistory('Description');
// Undo/Redo
RSL.StateManager.undo();
RSL.StateManager.redo();
// Presets
RSL.StateManager.savePreset('My Layout');
RSL.StateManager.loadPreset('My Layout');
RSL.StateManager.getPresetNames();
RSL.StateManager.deletePreset('My Layout');
// Import/Export
const data = RSL.StateManager.toJSON({ includeSchema: true });
RSL.StateManager.fromJSON(data, { container: '#app' });
// Layout engine ready
window.addEventListener('rsl:jsonlayout:ready', () => {});
// State changed
window.addEventListener('rsl:statechange', (e) => {
console.log(e.detail.state);
});