API Reference
API Reference
Complete public API for Sazami.
Note: The Sakko parser is now in the separate
@nisoku/sakkopackage. For the full Sakko syntax, see the Sakko Language Reference.
Core
compileSakko(source, target)
The main entry point. Parses a .sako source string, transforms it to a component tree, and renders it into a target DOM element.
import { compileSakko } from '@nisoku/sazami';
const source = `
<page {
card {
text(bold): "Hello World"
button(accent): "Click Me"
}
}>
`;
compileSakko(source, document.getElementById('app'));
Parameters:
source: string- Sakko DSL source code (angle brackets are auto-added if missing)target: HTMLElement- DOM element to render intooptions?: { tokens?: Record<string, string> }- Optional custom token overrides
Behavior:
- Registers all Sazami Web Components
- Injects theme CSS variables into
<head> - Parses source -> AST (uses
@nisoku/sakko) - Transforms AST -> VNode tree
- Renders VNode tree -> DOM
- Applies curvomorphism to
[curved]elements
Transformer
transformAST(node)
Transform an AST node into a VNode (virtual DOM node) or array of VNodes.
import { parseSakko } from '@nisoku/sakko';
import { transformAST } from '@nisoku/sazami';
const ast = parseSakko('<page { button(accent): Save }>');
const vnodes = ast.children.map(transformAST).flat();
// Returns: [{ type: "saz-button", props: { variant: "accent" }, children: ["Save"] }]
// For content components (text, heading, badge, etc.), content is in props.content:
const ast2 = parseSakko('<page { text(bold): "Hello" }>');
const vnode2 = transformAST(ast2.children[0]);
// Returns: { type: "saz-text", props: { weight: "bold", content: "Hello" }, children: [] }
render(vnode, parent)
Render a VNode tree into a DOM element.
import { render } from '@nisoku/sazami';
render(vnode, document.getElementById('app'));
Config
injectThemeCSS(customTokens?)
Inject theme CSS variables into the document <head>. Idempotent, updates existing theme if already injected.
import { injectThemeCSS } from '@nisoku/sazami';
// Use defaults
injectThemeCSS();
// Override specific tokens
injectThemeCSS({ 'color.primary': '#ff0000' });
generateThemeCSS(customTokens?)
Generate the complete theme CSS string without injecting it.
import { generateThemeCSS } from '@nisoku/sazami';
const css = generateThemeCSS();
// Returns: ":root { --saz-color-primary: #2563eb; ... }"
generateCSSVariables(tokens)
Convert a token map to CSS variable declarations.
import { generateCSSVariables } from '@nisoku/sazami';
generateCSSVariables({ 'color.primary': '#2563eb' });
// Returns: " --saz-color-primary: #2563eb;"
getTokenValue(key, customTokens?)
Look up a resolved token value.
import { getTokenValue } from '@nisoku/sazami';
getTokenValue('color.primary'); // "#2563eb"
Token Maps
Importable token maps for each category:
import { defaultTokens, colors, spacing, typography, radii, shadows, iconSizes } from '@nisoku/sazami';
Curvomorphism
applyCurvomorphism(element, options?)
Apply directional corner rounding to an element.
import { applyCurvomorphism } from '@nisoku/sazami';
applyCurvomorphism(element, {
radius: 'strong',
centerX: 500,
centerY: 400,
});
enableCurvomorphism(element, options?)
Conditionally apply curvomorphism if the element has the curved attribute.
import { enableCurvomorphism } from '@nisoku/sazami';
enableCurvomorphism(element);
Primitives API
registerComponents()
Register all Sazami Web Components with the browser’s custom elements registry. Called automatically by compileSakko.
import { registerComponents } from '@nisoku/sazami';
registerComponents();
parseModifiers(modifiers)
Convert an array of AST modifier nodes into a props object.
import { parseModifiers } from '@nisoku/sazami';
parseModifiers([
{ type: 'pair', key: 'accent', value: '' }, // flag modifier
{ type: 'pair', key: 'gap', value: 'large' }, // pair modifier
]);
// Returns: { variant: 'accent', gap: 'large' }
COMPONENT_REGISTRY
The component registry mapping custom element tags to Web Component classes:
import { COMPONENT_REGISTRY } from '@nisoku/sazami';
// Maps tag names to component classes, e.g.:
// { "saz-card": SazamiCard, "saz-button": SazamiButton, ... }
MODIFIER_MAP
The modifier flag mapping:
import { MODIFIER_MAP } from '@nisoku/sazami';
MODIFIER_MAP['accent']; // { variant: 'accent' }
MODIFIER_MAP['bold']; // { weight: 'bold' }
ICON_SVGS
A record mapping icon names to SVG markup strings. All 50+ built-in icons use currentColor and scale to their container.
import { ICON_SVGS } from '@nisoku/sazami';
// Available: play, pause, stop, previous, next, skip, back, forward,
// close, menu, search, settings, heart, star, check, plus, minus,
// edit, share, download, upload, refresh, home, up, down,
// mail, phone, calendar, clock, user, users, folder, file,
// image, camera, bell, lock, link, trash, copy, bookmark, pin, globe
ICON_SVGS['play']; // '<svg ...>...</svg>'
Base Component System
Sazami provides a declarative component system with typed properties, events, and handler management. See Component Base for full documentation.
@component(config)- Decorator for component metadataSazamiComponent- Base class for all componentsaddHandler()/removeHandler()/removeAllHandlers()- Handler trackingdispatch()/dispatchEventTyped()/onCleanup()- Event utilities
Sairin Signal Integration
Sazami primitives integrate with Sairin signals for reactive state management. Components can accept both static values and Sairin Signal or Derived values.
Note: For full details on Sairin’s signal system, see the Sairin documentation. Key concepts:
signal(path, initial)- Creates a reactive valuederived(path, fn)- Creates a computed valueeffect(fn)- Runs side effects reactivelyresource(loader, initial)- Async data fetching
Signal-Bound Properties
Most component properties support binding to signals:
| Component | Signal Properties |
|---|---|
text, badge, heading, label |
content |
button, icon-button |
disabled |
checkbox, switch, toggle, radio |
checked, disabled |
input, select, slider, progress |
value |
avatar, coverart, image |
src |
Basic Usage
import { signal, path } from '@nisoku/sairin';
// Create a signal
const text = signal(path("app", "message"), "Hello");
// Pass signal to component property
const el = document.createElement('saz-text');
el.content = text;
document.body.appendChild(el);
// Update signal - component re-renders automatically
text.set("World");
Derived Signals
import { signal, derived, path } from '@nisoku/sairin';
const firstName = signal(path("app", "firstName"), "John");
const lastName = signal(path("app", "lastName"), "Doe");
// Create derived signal
const fullName = derived(path("app", "fullName"), () =>
`${firstName.get()} ${lastName.get()}`
);
// Pass derived to component
const el = document.createElement('saz-text');
el.content = fullName;
Two-Way Binding
For form controls, changes in the UI automatically update the signal:
import { signal, path } from '@nisoku/sairin';
const inputValue = signal(path("app", "inputValue"), "");
// Input updates the signal on every keystroke
const input = document.createElement('saz-input');
input.value = inputValue;
document.body.appendChild(input);
// Programmatic updates also work
inputValue.set("Hello");
Boolean State
import { signal, path } from '@nisoku/sairin';
const isDisabled = signal(path("app", "disabled"), false);
const button = document.createElement('saz-button');
button.disabled = isDisabled;
// Disable the button
isDisabled.set(true);
Resource Integration
import { signal, path, effect, resource } from '@nisoku/sairin';
const userData = resource(
() => fetch('/api/user').then(r => r.json()),
null
);
// Derive a string value from the resource
const userName = signal(path("app", "userName"), '');
effect(() => {
userName.set(userData.value.get()?.name ?? '');
});
const el = document.createElement('saz-text');
el.content = userName;
Reactivity Model
Sazami uses Sairin’s effect() for reactive bindings:
- One-way: Signal changes propagate to component properties
- Two-way: Form inputs also write back to the signal
- Automatic cleanup: Bindings are cleaned up when the component is removed from the DOM
Error Handling
Sazami uses Satori for structured logging. Errors are logged with context and suggestions.
Error Functions
import {
propertyError,
eventError,
renderError,
bindingError,
unknownComponentError,
} from '@nisoku/sazami';
// Property configuration errors
propertyError('Invalid property value', {
tag: 'saz-button',
suggestion: 'Use a valid variant: default, accent, or ghost',
});
// Event dispatch errors
eventError('Event not defined in metadata', {
tag: 'saz-input',
suggestion: 'Add the event to your @component config',
});
// Render errors
renderError('Failed to render component', {
suggestion: 'Check template syntax and styles',
});
// Binding errors
bindingError('Invalid binding', {
property: 'value',
suggestion: 'Use bind:value for two-way binding',
});
// Unknown component warning
unknownComponentError('my-component', 'Use saz- prefix');
Integration with Sakko
Sakko (parser) also uses Satori for structured errors:
import {
tokenizerError,
parserError,
} from '@nisoku/sakko';
tokenizerError('Invalid syntax', {
suggestion: 'Check for missing quotes',
});
parserError('Unexpected token', {
cause: 'missing closing tag',
});
Accessibility
All interactive primitives include full keyboard support following WAI-ARIA patterns.
For component-specific props and methods, see Component Base and the Primitives reference.
Keyboard Navigation
| Component | Keys | Behavior |
|---|---|---|
| Select | Enter/Space | Open/close dropdown |
| Select | Escape | Close dropdown |
| Select | Arrow Up/Down | Navigate options |
| Select | Home/End | First/last option |
| Tabs | Arrow Left/Right | Switch tabs |
| Tabs | Enter/Space | Activate focused tab |
| Modal | Escape | Close modal |
| Toast | Escape | Dismiss toast |
| Button | Enter/Space | Activate (native) |
| Checkbox | Enter/Space | Toggle (native) |
| Toggle | Enter/Space | Toggle (native) |
| Slider | Arrow Left/Right | Adjust value |
Focus Management
- Focus is properly managed when opening/closing modals and selects
- Tab order follows visual layout
- Focus indicators are visible
Types
All TypeScript types are exported:
import type {
VNode,
ComponentDefinition,
CurvomorphismOptions,
SazamiComponentConfig,
PropertyConfig,
EventConfig,
} from '@nisoku/sazami';