Components
Learn how to create and use components in SemaJSX
Components
Components are the building blocks of SemaJSX applications. They are simple functions that return JSX.
Functional Components
In SemaJSX, components are just functions that return VNodes:
/** @jsxImportSource semajsx/dom */
function Greeting({ name }: { name: string }) {
return <h1>Hello, {name}!</h1>;
}
// Usage
<Greeting name="Alice" />;
Props
Props are passed as the first argument to component functions:
interface ButtonProps {
label: string;
onClick: () => void;
variant?: "primary" | "secondary";
}
function Button({ label, onClick, variant = "primary" }: ButtonProps) {
return (
<button class={`btn btn-${variant}`} onClick={onClick}>
{label}
</button>
);
}
Children
Access children via the children prop:
interface CardProps {
title: string;
children: VNode | VNode[];
}
function Card({ title, children }: CardProps) {
return (
<div class="card">
<h2>{title}</h2>
<div class="card-content">{children}</div>
</div>
);
}
// Usage
<Card title="My Card">
<p>Card content goes here</p>
</Card>;
Reactive Components
Use signals to create reactive components:
import { signal } from "semajsx/signal";
function Counter() {
const count = signal(0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => count.value++}>+1</button>
<button onClick={() => count.value--}>-1</button>
</div>
);
}
Composition
Compose components to build complex UIs:
function UserProfile({ user }: { user: User }) {
return (
<Card title={user.name}>
<Avatar src={user.avatar} />
<Bio text={user.bio} />
<SocialLinks links={user.social} />
</Card>
);
}
Conditional Rendering
Use JavaScript expressions for conditional rendering:
function LoginButton({ isLoggedIn }: { isLoggedIn: boolean }) {
return <div>{isLoggedIn ? <button>Logout</button> : <button>Login</button>}</div>;
}
Lists
Map over arrays to render lists:
function TodoList({ todos }: { todos: Todo[] }) {
return (
<ul>
{todos.map((todo) => (
<li key={todo.id}>
<input type="checkbox" checked={todo.done} />
<span>{todo.text}</span>
</li>
))}
</ul>
);
}
Keys are important
Always provide a unique key prop when rendering lists to help SemaJSX identify items.
Component API
Components can receive a second parameter with additional APIs:
import { context } from "semajsx";
const ThemeContext = context<Theme>("theme");
function ThemedButton(props: ButtonProps, ctx) {
const theme = ctx?.inject(ThemeContext) ?? defaultTheme;
return <button style={{ background: theme.primary }}>{props.label}</button>;
}
Best Practices
- Keep components small - One component, one responsibility
- Use TypeScript - Define prop interfaces for type safety
- Destructure props - Make dependencies explicit
- Extract reusable logic - Use composition over inheritance
Next Steps
- Learn about Context API for state management
- Explore Refs for DOM access
- Check out Component Patterns