Props
Props are the way to pass data from a parent component to a child component. In Effuse, props are fully typed and reactive.
Defining Props
To define props, you pass a TypeScript interface as the first generic argument to the define function. The define function actually accepts two generic arguments:
Props Type (
P): Defines the shape of props passed to the component.Exposed Values (
E): Defines the shape of the object returned by thescriptfunction and available in thetemplate.
import { define, signal, type Signal } from '@effuse/core';
interface UserCardProps {
name: string;
age: number;
}
interface UserCardExposed {
capitalizedName: Signal<string>;
}
const UserCard = define<UserCardProps, UserCardExposed>({
script: ({ props }) => {
const capitalizedName = signal(props.name.toUpperCase());
return { capitalizedName };
},
template: ({ capitalizedName }, props) => (
<div class="user-card">
<h2>{capitalizedName}</h2>
<p>Age: {props.age}</p>
</div>
),
});
Reactivity in Props
In the script function, props is a reactive object. If a parent passes a signal as a prop, accessing that prop inside a computed or watchEffect tracks it.
import { define, computed, unref } from '@effuse/core';
interface CounterProps {
count: number; // Can be passed as a number or a Signal<number>
}
const DoubleCounter = define<CounterProps>({
script: ({ props }) => {
// This computed will update whenever the parent's 'count' signal changes
const double = computed(() => unref(props.count) * 2);
return { double };
},
template: ({ double }) => <div>Double count: {double}</div>,
});
Default Values
You can handle default values using standard JavaScript patterns or computed for reactive defaults.
import { define, computed, unref } from '@effuse/core';
interface ButtonProps {
variant?: 'primary' | 'secondary';
}
const Button = define<ButtonProps>({
script: ({ props }) => {
// Reactive default value
const safeVariant = computed(() => unref(props.variant) ?? 'primary');
return { safeVariant };
},
template: ({ safeVariant, children }) => (
<button class={`btn btn-${safeVariant.value}`}>{children}</button>
),
});
Passing Props
You pass props to components just like standard HTML attributes.
// Using static values
<UserCard name="Alice" age={30} isAdmin />;
// Using signals
const age = signal(25);
<UserCard name="Bob" age={age} />;
Note that when passing a signal (like age={age}), Effuse automatically unwraps it in the DOM but keeps the reactivity connection alive for the component logic.
Children Prop
The children prop is special. It contains the content passed inside the component tags.
const Container = define({
script: () => ({}),
template: ({ children }) => <div class="container">{children}</div>,
});
// Usage
<Container>
<h1>Hello</h1>
</Container>;
Next Steps