import { ui } from "@rezi-ui/core";
import { createNodeApp } from "@rezi-ui/node";
type State = {
items: Array<{ id: string; name: string }>;
confirmDeleteId: string | null;
};
const app = createNodeApp<State>({
initialState: {
items: [
{ id: "1", name: "Project Alpha" },
{ id: "2", name: "Project Beta" },
{ id: "3", name: "Project Gamma" },
],
confirmDeleteId: null,
},
});
app.view((state) => {
const confirmItem = state.confirmDeleteId
? state.items.find((i) => i.id === state.confirmDeleteId)
: null;
return ui.layers([
// Main content
ui.page({ p: 1 }, [
ui.panel("Projects", [
ui.column({ gap: 1 }, [
...state.items.map((item) =>
ui.row({ key: item.id, gap: 2, justify: "between" }, [
ui.text(item.name),
ui.button({
id: `delete-${item.id}`,
label: "Delete",
intent: "danger",
onPress: () =>
app.update((s) => ({ ...s, confirmDeleteId: item.id })),
}),
])
),
]),
]),
]),
// Modal overlay (conditional)
confirmItem &&
ui.modal({
id: "confirm-delete",
title: "Confirm Deletion",
width: 50,
backdrop: "dim",
content: ui.column({ gap: 1 }, [
ui.text(`Delete "${confirmItem.name}"?`),
ui.text("This action cannot be undone.", { variant: "caption" }),
]),
actions: [
ui.button({
id: "cancel",
label: "Cancel",
intent: "secondary",
onPress: () => app.update((s) => ({ ...s, confirmDeleteId: null })),
}),
ui.button({
id: "confirm",
label: "Delete",
intent: "danger",
onPress: () =>
app.update((s) => ({
...s,
items: s.items.filter((it) => it.id !== s.confirmDeleteId),
confirmDeleteId: null,
})),
}),
],
onClose: () => app.update((s) => ({ ...s, confirmDeleteId: null })),
returnFocusTo: confirmItem ? `delete-${confirmItem.id}` : undefined,
}),
]);
});
app.keys({
"ctrl+c": () => app.stop(),
q: () => app.stop(),
escape: () => app.update((s) => ({ ...s, confirmDeleteId: null })),
});
await app.start();