Templating
JSX, lowercase events, and lists from data.
Prefer JSX. Interpolated values escape. Use class, not className.
const const Hello: ({ name }: {
name: string;
}) => View
Hello = ({ name: stringname }: { name: stringname: string }) => (
<IntrinsicElements[string]: anyp class: stringclass="lede">Hello, {name: stringname}</IntrinsicElements[string]: anyp>
);
Use h() when a file cannot use the JSX runtime. See Without JSX.
Events
Event props are lowercase native names: onclick, onchange, onsubmit. Use a plain function. You do not need a special action wrapper on the client.
import { const atom: AtomFnatom } from "ilha";
const const Counter: () => ViewCounter = () => {
const const count: AtomHandle<number>count = atom<number>(init: number | Atom<number> | Effect<number, any, any> | Stream<number, any, any>): AtomHandle<number>atom(0);
return (
<IntrinsicElements[string]: anybutton
type: stringtype="button"
onclick: () => voidonclick={() => const count: AtomHandle<number>count.AtomHandle<number>.update(f: (current: number) => number): voidupdate((n: numbern: number) => n: numbern + 1)}
>
{const count: AtomHandle<number>count}
</IntrinsicElements[string]: anybutton>
);
};
On a server island, bind oxidejs actions with .with(...) on event props so SSR can serialize frame sentinels. Plain client islands keep plain handlers. See Server islands.
Lists
Atoms hold data. Map an array during render:
import { const atom: AtomFnatom } from "ilha";
type type Item = {
id: string;
text: string;
}
Item = { id: stringid: string; text: stringtext: string };
const const List: () => ViewList = () => {
const const items: AtomHandle<Item[]>items = atom<Item[]>(init: Item[] | Atom<Item[]> | Effect<Item[], any, any> | Stream<Item[], any, any>): AtomHandle<Item[]>atom<type Item = {
id: string;
text: string;
}
Item[]>([{ id: stringid: "1", text: stringtext: "One" }]);
return (
<IntrinsicElements[string]: anyul>
{const items: AtomHandle
() => Item[]
items().Array<Item>.map<View>(callbackfn: (value: Item, index: number, array: Item[]) => View, thisArg?: any): View[]Calls a defined callback function on each element of an array, and returns an array that contains the results.map((item: Itemitem) => (
<IntrinsicElements[string]: anyli key: stringkey={item: Itemitem.id: stringid}>{item: Itemitem.text: stringtext}</IntrinsicElements[string]: anyli>
))}
</IntrinsicElements[string]: anyul>
);
};
When items changes, the component reruns and morphs the list. Keys on li reuse DOM nodes when the array shifts.
For live server lists, paint a Stream into a hole. See Streams.