From v0.0.x

Imports

You now import from dreamland/core

// old
import "dreamland/dev"; // or whatever

// new
import { css, createState, type Component } from "dreamland/core";

Vite

vite-plugin-dreamland is replaced with dreamland/vite's jsxPlugin, which is only used for non-TypeScript projects.

// old
import { defineConfig } from "vite";
import { dreamlandPlugin } from "vite-plugin-dreamland";

export default defineConfig({
	plugins: [dreamlandPlugin()],
});

// new
import { jsxPlugin } from "dreamland/vite";
import { defineConfig } from "vite";

export default defineConfig({
	plugins: [jsxPlugin()],
});

Styles

For inline styles you now need to list the css name verbatim.

// old
<div style={{ minWidth: "300px" }}>

// new
<div style={{ "min-width": "300px" }}>

For classes you now need to define them outside the component.

// old
const App: Component<{}, {}> = function () {
	this.css = `
      height: 100vh;
    `;

	const red = css`
		color: red;
	`;

	return (
		<div>
			<NavBar />
			<div class={red}>this text is red!</div>
		</div>
	);
};

// new
const App: Component<{}, {}> = function () {
	return (
		<div>
			<NavBar />
			<div class="red">this text is red!</div>
		</div>
	);
};
App.style = css`
	:scope {
		height: 100vh;
	}
	.red {
		color: red;
	}
`;

Reactivity

useChange(x, () => {}) is now replaced with use(x).listen(() => {})

// old
export const NavBar: Component<
	{},
	{
		pages: Record<string, { name: string; page: Component<any, any> }>;
		path: string;
	}
> = function () {
	this.path = new URL(document.URL).pathname;
	useChange(this.path, () => {
		let url = new URL(document.URL);
		url.pathname = this.path;
		if (window.location.toString() != url.toString()) {
			window.location.assign(url);
		}
	});

	return <div>Nav Bar</div>;
};

// new
export const NavBar: Component<
	{},
	{
		pages: Record<string, { name: string; page: ComponentChild }>;
		path: string;
	}
> = function () {
	this.path = new URL(document.URL).pathname;
	use(this.path).listen(() => {
		let url = new URL(document.URL);
		url.pathname = this.path;
		if (window.location.toString() != url.toString()) {
			window.location.assign(url);
		}
	});

	return <div>Nav Bar</div>;
};

use(x, (x) => x) with use(x).map((x) => x)

// old
<div>
  {use(this.path, () => this.pages[this.path].page(this))}
</div>

// new
<div>
  {use(this.path).map((path) => this.pages[path].page)}
</div>

$if(x, yes, no) is now use(x).andThen(yes, no)

// old
{
	$if(this.mobile, <Mobile />, <Desktop />);
}

// new
{
	use(this.mobile).andThen(<Mobile />, <Desktop />);
}

this Object

Many items that were once accessed by this. are now accessed by cx. and JSX.Element is replaced with ComponentChild

// old
export const Row: Component<{}, { children: JSX.Element }> = function () {
	this.mount = () => {
		(this.root.children[0] as HTMLDivElement).addEventListener(
			"mouseenter",
			() => {
				console.log("enter!");
			}
		);
	};
	return <div>{this.children}</div>;
};

// new
export const Row: Component<{ children: ComponentChild }, {}> = function (cx) {
	cx.mount = () => {
		(cx.root.children[0] as HTMLDivElement).addEventListener(
			"mouseenter",
			() => {
				console.log("enter!");
			}
		);
	};
	return <div>{cx.children}</div>;
};