Sakko Language Reference
Sakko Language Reference
The Sakko DSL is a bracket-based markup language for describing UI trees. It compiles to Sazami component trees which render to the DOM.
File Extension
Sakko files use the .sako extension.
Syntax Overview
Root Blocks
Every .sako file has one root block wrapped in angle brackets:
<name {
...children
}>
Note: The
compileSakko()function auto-wraps source that is missing<>brackets, so both<card { ... }>andcard { ... }work when using the API. However, always have the habit to add<>brackets.
Example:
<page {
card { text: Hello }
}>
Block Elements
Block elements contain child elements inside curly braces:
element {
child1: value
child2 { ... }
}
Example:
<card {
text(bold): "Title"
text(dim): "Subtitle"
button: "Click"
}>
Inline Elements
Inline elements have no children: just a name, optional modifiers, and a value:
name: value
name(modifiers): value
Example:
text: Hello
button(accent large): Save
icon: play
Void Elements
Elements that need no value or children can stand alone:
divider;
spacer(large);
These are parsed as inline elements with an empty value. Useful for separators, spacers, and structural markers.
Modifiers
Modifiers are placed in parentheses after the element name. They configure the element’s appearance and behavior.
Flags (Boolean)
Space-separated tokens:
button(accent large bold): Save
card(curved): { ... }
text(dim small): Label
Key-Value Pairs
Some tokens take a following value. Values can be bare identifiers or quoted strings:
grid(cols 3 gap large): [...]
row(gap medium): [...]
input(placeholder "Enter your name" type "email"): ""
image(src "photo.jpg" alt "A photo"): ""
The parser recognizes these keys as pairs: cols, gap, radius, size, variant, layout, placeholder, type, src, alt, icon, label, value, center-point.
Modifier Categories
| Category | Values | Maps To |
|---|---|---|
| Variant | accent, primary, secondary, danger, success |
variant attribute |
| Tone | dim, dimmer |
tone attribute |
| Size | small, medium, large, xlarge |
size attribute |
| Weight | bold, normal, light |
weight attribute |
| Layout | row, column |
layout attribute |
| Alignment | center, start, end |
align attribute |
| Justify | space-between, space-around |
justify attribute |
| Shape | round, square, pill |
shape attribute |
| Curvomorphism | curved, flat |
curved attribute |
| State | disabled, active, loading, checked |
boolean attributes |
| Wrap | wrap, nowrap |
wrap attribute |
Strict validation: Unknown modifier flags throw an error. If you need a custom modifier, add it to
MODIFIER_MAPbefore use.
Lists
Lists group multiple sibling elements, with items separated by commas:
<grid(cols 3) {
card { text: One },
card { text: Two },
card { text: Three }
}>
Lists can appear after a colon or directly:
row: {button: A, button: B}
row {button: A, button: B}
Inline Siblings with Semicolons
Use semicolons to place multiple inline elements on one line:
<controls {
button: play; button: pause; badge(accent): LIVE
}>
Semicolons work at any nesting level, including root:
<page {
text: A; text: B; text: C
}>
Strings
- Bare words for simple values (no spaces):
text: Hello - Quoted strings for values with spaces or special characters:
text: "Hello World"
Comments
Single-line comments start with //:
// This is a comment
<card {
// Comments work anywhere
text: Content // Inline comments too
}>
Complete Example
<player {
// Main card with horizontal layout
card(row medium center curved) {
coverart(round): "album.jpg"
details(column gap small) {
text(bold large): "Midnight City"
text(dim): "M83"
badge(accent): "Synthwave"
}
controls(row gap small) {
icon-btn: previous;
icon-btn(accent large): play;
icon-btn: next
}
}
// Queue section
card(curved medium) {
heading: "Up Next"
column(gap small): [
row(space-between gap medium) {
text: "Track 1"
text(dim small): "3:45"
},
row(space-between gap medium) {
text: "Track 2"
text(dim small): "4:12"
}
]
}
// Bottom controls
row(space-between gap large) {
button(dim): Library
button(accent): Discover
button(dim): Settings
}
}>
AST Output
The parser produces an AST with these node types:
| Node Type | Fields | Description |
|---|---|---|
root |
name, modifiers, children |
Top-level container |
element |
name, modifiers, children |
Block element with children |
inline |
name, modifiers, value |
Leaf element with text value |
list |
items |
Comma-separated group |
Modifiers are either { type: "flag", value: string } or { type: "pair", key: string, value: string }.