HTML State
This example shows one of Ornata’s most useful HTML-first patterns: deriving initial component state from markup. It gives server-rendered data and configuration a direct path into component behavior at runtime.
With the exception of more complex state properties, such as functions, component state can be initialized from corresponding data-* attributes on the component’s root element. In this example, the server provides a count value in the HTML, which the Ornata component reads during initialization and uses as the starting point for its state.
Live Demo
Section titled “Live Demo”<!-- 👇 The server-provided state is applied directly to the root element --><section data-counter data-count="3"> <p> <span>Server count:</span> <strong data-count-value></strong> </p> <button data-count-button>Increment</button></section>Component
Section titled “Component”import { defineComponent } from 'ornata';
export const Counter = defineComponent({ name: 'Counter', state: { count: { default: 0, type: Number }, }, elements: { value: { query: '[data-count-value]' }, button: { query: '[data-count-button]' }, }, methods: { increment() { this.state.count += 1; }, }, render: { value() { return { text: String(this.state.count), }; }, button() { return { attributes: { type: 'button', }, events: { click: () => this.methods.increment(), }, }; }, },});import { defineComponent } from 'ornata';
interface CounterState { count: number; label: string;}
export const Counter = defineComponent<{ state: CounterState; elements: { value: Element | null; button: Element | null; }; methods: { increment(): void; };}>({ name: 'Counter', state: { count: { default: 0, type: Number }, }, elements: { value: { query: '[data-count-value]' }, button: { query: '[data-count-button]' }, }, methods: { increment() { this.state.count += 1; }, }, render: { value() { return { text: String(this.state.count), }; }, button() { return { attributes: { type: 'button', }, events: { click: () => this.methods.increment(), }, }; }, },});Counter.mount('[data-counter]');What happens
Section titled “What happens”The component definition provides defaults:
count: 0
But the HTML root provides:
data-count="3"
So the mounted instance starts with:
count = 3
Override from JavaScript
Section titled “Override from JavaScript”If you mount with initialState, that wins over the HTML values:
Counter.mount('[data-counter]', { count: 10,});Now the starting count would be 10 instead of 3.