# Getting Started

!!! info
	This framework assumes that you have a good fundamental understanding of JavaScript and HTML. If not, [MDN](https://developer.mozilla.org/docs/Web/JavaScript) is a good place to start.

To develop an rvx application locally, you need a recent version of [NodeJS](https://nodejs.org/) or any other compatible JavaScript runtime.

You can use the commands below to setup a minimal rvx project using [TypeScript](https://www.typescriptlang.org/) and [Vite](https://vitejs.dev/):

```bash
# Create a "my-app" directory from rvx's "vite" template project:
npx degit mxjp/rvx/templates/vite my-app

# Move into "my-app":
cd my-app

# Install dependencies:
npm install

# Start a development server:
npm start
```

## Entry Point
After setting up the quick start template, you can find the main entry point in `src/main.tsx`:
```jsx
import { leak, mount } from "rvx";

leak(() => {
	mount(
		document.body,
		<h1>Hello World!</h1>
	);
});
```

+ The `<h1>Hello World!</h1>` expression directly creates an element.
+ `mount` takes whatever content is supported by rvx and appends it to the specified element.
+ `leak` provides an infinitely long lifecycle.

## State & Reactivity
Reactivity is entirely based on signals which are objects that hold an arbitrary value:
```jsx
import { $ } from "rvx";

// Create a signal with the initial value 0:
const count = $(0);
```

When a signal is used directly or its value is accessed through a function call, the signal can notify its observers when the value changes:
```jsx
import { $, mount } from "rvx";

const count = $(0);

mount(
	document.body,
	<>
		{/* Using the signal directly is reactive: */}
		Current count: {count}

		{/* Accessing its value through a function is reactive: */}
		Is even count: {() => (count.value & 1) === 0}

		{/*
			Using the value directly is not reactive because
			rvx has no way of re-evaluating the expression:
		*/}
		Initial count: {count.value}
	</>
);
```

To replace a signal value, you can set the `value` property:
```jsx
count.value = 1;
```

To deeply update an object, modify it directly and manually notify observers:
```jsx
const values = $([7, 42]);

// This will modify the inner value without tracking:
values.inert.push(77);

// Manually notify observers:
values.notify();
```

## Basic Rendering
JSX expressions directly create HTML elements:
```jsx
<button>Click me!</button>
```

By default, attribute names are the same as in HTML:
```jsx
<img alt="An image" src="..." />
```

Attributes, set to `false`, `undefined` or `null` are removed. `true` is set as an empty string:
```jsx
<input disabled={false} /> // <input>
<input disabled={true} /> // <input disabled="">
```

Attributes prefixed with `prop:` are set using JavaScript properties:
```jsx
<input type="text" prop:value="Hello World!" />
```

Signals or functions used as attribute values are reactive:
```jsx
<input type="number" prop:value={count}>
<input type="number" prop:value={() => count.value}>
```

## Event Listeners
Attributes prefixed with `on:` are added as event listeners.
```jsx
<button on:click={event => {
	console.log("Clicked", event.target);
}}>Click me!</button>
```

## Conditional Rendering
To render conditional or repeated content rvx uses so-called **Views** which are sequences of DOM nodes that can change over time.

The `Show` component renders content when a condition is met:
```jsx
import { $, mount, Show } from "rvx";

const showMessage = $(false);

mount(
	document.body,
	<>
		<button on:click={() => { showMessage.value = !showMessage.value }}>
			Toggle message
		</button>

		<Show when={showMessage}>
			{() => <h1>Hello World!</h1>}
		</Show>
	</>
);
```

The `For` component repeats content for each item in an iterable:
```jsx
import { $, mount, For } from "rvx";

const values = $<number[]>([]);

mount(
	document.body,
	<>
		<button on:click={() => {
			values.inert.push(Date.now());
			values.notify();
		}}>
			Add current time
		</button>

		<ul>
			<For each={values}>
				{value => <li>{value}</li>}
			</For>
		</ul>
	</>
);
```

In addition to `Show` and `For`, rvx provides some more view types you can find [here](./reference/core/views/index.md) or you can implement your own views for special use cases.

## Components
Components in rvx are just functions that return arbitrary content. They are called once when the component is rendered.
```jsx
function Message() {
	return <h1>Hello World!</h1>;
}

// Using the component:
<Message />;
```

Properties are passed as is via the `props` argument and are static by default.
```jsx
function Message(props: { message: string; }) {
	return <h1>{props.message}</h1>;
}

// Using the component:
<Message message="Hello World!" />;
```

To make properties reactive, you can use the `Expression` type which can be a static value, a signal or a function:
```jsx
import { Expression } from "rvx";

function Message(props: { message: Expression<string>; }) {
	return <h1>{props.message}</h1>;
}

// Using the component:
<Message message="Hello World!" />;
<Message message={() => "Hello World!"} />;
<Message message={someSignal} />;
```

To compute something from an expression or to evaluate it, you can use the `map` and `get` functions:
```jsx
import { Expression, map, get } from "rvx";

function Message(props: { message: Expression<string>; }) {
	// "get" reactively returns the current value of an expression:
	console.log("Initial message:", get(props.message));

	// "map" applies a function to the expression result:
	return <h1>{map(props.message, m => m.toUpperCase())}</h1>;
}
```

To allow components to update a value, you can use the `Signal` type:
```jsx
import { $, mount, Signal } from "rvx";

function TextInput(props: { value: Signal<string>; }) {
	return <input
		type="text"
		prop:value={props.value}
		on:input={event => {
			props.value.value = (event.target as HTMLInputElement).value;
		}}
	/>;
}

const text = $("Hello World!");
<TextInput value={text} />;
```

Component children are passed via the `children` property:
```jsx
function Message(props: { children?: unknown; }) {
	return <h1>{props.children}</h1>;
}

<Message>Hello World!</Message>;
```

## Moving on...
From here, you can take a look at [the reference](./reference/index.md) or [the examples](./examples/stopwatch.md) to get a brief overview.

To develop a deep understanding of rvx, you should read through the core reference in the order below:

+ [Lifecycle](./reference/core/lifecycle.md) / [Context](./reference/core/context.md)
+ [Signals](./reference/core/signals.md)
+ [Elements](./reference/core/elements.md)
+ [Views](./reference/core/views/index.md)
+ [Components](./reference/core/components.md)
