State

Data that is stored within a component is called its state. State can be simple variables, or it can be placed in an object and wrapped with the $watch function to make it reactive and update the UI when it is changed:

export default function Component() {
	const $state = $watch({
		count: 1
	})

	@render {
		<div>
			<p>
				The count is {$state.count}.
			</p>
			<button onclick={() => $state.count++}>
				Increment
			</button>
		</div>
	}
}

The $watch function is automatically imported into component files if used (along with a few other functions). By convention, reactive objects should start with a $ so that it is easy to see at a glance which statements are reactive in your markup.

Dependent state can be created using object properties:

export default function Component() {
	const $state = $watch({
		count: 1,
		get isEven() {
            return this.count % 2 === 0
		}
	})

	@render {
		<div>
			<p>
				The count is {$state.isEven ? "even" : "odd"}!
			</p>
			<button onclick={() => $state.count++}>
				Increment
			</button>
		</div>
	}
}

The $run function

Another function that is automatically imported into your components is $run. Calling $run sets up a function that is run on component initialization and when any reactive values accessed within it are changed:

export default function Component() {
	const $state = $watch({
		count: 1,
	})

	$run(() => {
		if ($state.count > 5) {
			document.getElementById("text").style.fontSize = "x-large"	
		}
	})

	@render {
		<div>
			<p id="text">
				The count is {$state.count}.
			</p>
			<button onclick={() => $state.count++}>
				Increment
			</button>
		</div>
	}
}

Behind the scenes, $run is called in the @render block to set up reactive text, attributes and statements.

The $mount function

The $mount function is like the $run function, but it delays its first run until after the @render block has been completed and all elements have been mounted. It is automatically imported into your component if used.

The $unwrap function

The $unwrap function returns the underlying object from a state object returned from $watch. It is automatically imported into your component if used.

Props

A component function can accept a $props component containing the properties that were passed to the component:

export default function Component($props: { name: string }) {
	@render {
		<p>
			Hello, {name}!
		</p>
	}
}

Playground

Input

Output