Scenario The scenario feature allows you to systematically manage and reuse complex dialog flows. You can group multi-step dialogs or conditional flows into a single logical unit.
Basic Object Style # The simplest and most intuitive way is to define a scenario as an object:
// 로그인 시나리오 정의
const loginScenario = grunfeld.scenario("login", {
showLoginForm: () => {
grunfeld.add(() => ({
element: <LoginForm />,
position: "center",
}));
},
showLoading: () => {
grunfeld.remove(); // 이전 단계 정리
grunfeld.add(() => ({
element: "Loading...",
position: "center",
}));
},
showSuccess: () => {
grunfeld.remove();
grunfeld.add(() => ({
element: "로그인 성공!",
position: "top-right",
}));
},
});
// 사용법 - 동적 메서드 접근
await loginScenario.showLoginForm(); // 특정 단계 실행
await loginScenario.showLoading();
await loginScenario.showSuccess();Each step can be called as a method, and since it returns a Promise, you can execute them sequentially using await.
Separated Style (Advanced) # You can separate control logic and implementation to construct more complex scenarios:
// 분리된 시나리오 정의
const advancedScenario = grunfeld.scenario(
"user-management",
// 제어 로직 (factory)
(cliche) => ({
processUser: async (user) => {
if (user.isPremium) {
await cliche.showPremiumContent();
} else {
await cliche.showBasicContent();
}
await cliche.logActivity();
},
}),
// 실제 구현 (implementation)
{
showPremiumContent: () => {
grunfeld.add(() => "프리미엄 콘텐츠");
},
showBasicContent: () => {
grunfeld.add(() => "기본 콘텐츠");
},
logActivity: () => {
console.log("사용자 활동 기록됨");
},
}
);
// 사용법
await advancedScenario.processUser({ isPremium: true });This approach separates business logic from UI implementation, improving maintainability.
Passing Parameters # You can implement dynamic behavior by passing parameters to scenario steps:
// 매개변수를 받는 시나리오 정의
const userScenario = grunfeld.scenario("user-flow", {
welcomeUser: ({ userName, userType }) => {
grunfeld.add(() => ({
element: `${userName}님 (${userType}) 환영합니다!`,
position: "center",
}));
},
showDashboard: ({ permissions = [] }) => {
grunfeld.add(() => ({
element: `대시보드 (권한: ${permissions.join(", ")})`,
position: "center",
}));
},
});
// 개별 단계에 매개변수 전달 (동적 메서드 접근)
await userScenario.welcomeUser({
userName: "홍길동",
userType: "관리자",
});
await userScenario.showDashboard({
permissions: ["read", "write", "admin"],
});You can receive user input and pass it to the next step or process it:
const registrationScenario = grunfeld.scenario("registration", {
getUserName: async () => {
const name = await grunfeld.add<string>((removeWith) => ({
element: (
<div>
<h3>이름을 입력하세요</h3>
<input
type="text"
onKeyPress={(e) => {
if (e.key === "Enter") {
removeWith(e.target.value);
}
}}
/>
</div>
),
position: "center",
}));
console.log("입력받은 이름:", name);
return name;
},
confirmData: async () => {
const confirmed = await grunfeld.add<boolean>((removeWith) => ({
element: (
<div>
<p>정보가 맞습니까?</p>
<button onClick={() => removeWith(true)}>확인</button>
<button onClick={() => removeWith(false)}>취소</button>
</div>
),
position: "center",
}));
if (!confirmed) {
throw new Error("사용자가 취소했습니다");
}
},
});API Reference # Main Scenario API methods:
scenario.step(name, params): Execute a specific stepscenario.run(paramsMap): Execute all steps sequentiallyscenario.getSteps(): Return list of stepsscenario.hasStep(name): Check if step existsscenario.clone(newName): Clone scenario