Install
$ agentstack add skill-foxhound87-skills-mobx-react-form-multi-step ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Skill: mobx-react-form-multi-step
Mission
Guide the user through building multi-step wizard forms using mobx-react-form with nested field groups, per-step validation, step indicators, and final submission.
Use this skill when the user needs to:
- Build a multi-step registration/checkout wizard
- Validate each step before advancing
- Track completed steps visually
- Show a review screen with all collected data
- Submit all steps together
Concept
Each step is a nested field group (dot-notation) within a single form instance. React state tracks the current step, completed steps, and per-step errors. Step navigation gates progression on validation. The review step shows accumulated data before final submission.
Form
├── step1 (group)
│ ├── firstName
│ ├── lastName
│ ├── email
│ └── phone
├── step2 (group)
│ ├── street
│ ├── city
│ ├── zipCode
│ └── country
└── step3 (group)
├── username
├── password
└── confirmPassword
Form Setup
Fields definition (separated mode with dot-notation groups)
const fields = [
'step1.firstName',
'step1.lastName',
'step1.email',
'step1.phone',
'step2.street',
'step2.city',
'step2.zipCode',
'step2.country',
'step3.username',
'step3.password',
'step3.confirmPassword',
];
Validation rules per field
const rules = {
'step1.firstName': 'required|string|min:2',
'step1.email': 'required|email',
'step3.password': 'required|string|min:6',
'step3.confirmPassword': 'required|string|min:6|same:step3.password',
// ...
};
Initial values
const values = {
step1: { firstName: 'John', lastName: 'Doe', email: 'john@example.com', phone: '+1 555-1234' },
step2: { street: '456 Oak Avenue', city: 'San Francisco', zipCode: '94102', country: 'USA' },
step3: {},
};
Component Walkthrough
Step definitions
const steps = [
{ key: 'step1', label: 'Personal Info', icon: User },
{ key: 'step2', label: 'Address', icon: MapPin },
{ key: 'step3', label: 'Account', icon: Settings },
{ key: 'review', label: 'Review', icon: ClipboardCheck },
];
const stepFields = {
step1: ['firstName', 'lastName', 'email', 'phone'],
step2: ['street', 'city', 'zipCode', 'country'],
step3: ['username', 'password', 'confirmPassword'],
};
State management
const [currentStep, setCurrentStep] = useState(0);
const [completedSteps, setCompletedSteps] = useState(new Set());
const [errors, setErrors] = useState({});
Group access
const stepGroups = useMemo(() => ({
0: form.$('step1'),
1: form.$('step2'),
2: form.$('step3'),
}), [form]);
Per-step validation
const validateStep = useCallback(async (stepIndex) => {
const group = stepGroups[stepIndex];
if (!group) return true;
await group.validate({ showErrors: true });
const valid = group.isValid;
if (!valid) {
setErrors((prev) => ({ ...prev, [stepIndex]: group.errors() }));
} else {
setErrors((prev) => { const next = { ...prev }; delete next[stepIndex]; return next; });
}
return valid;
}, [stepGroups]);
Navigation
const handleNext = useCallback(async () => {
const valid = await validateStep(currentStep);
if (!valid) return;
setCompletedSteps((prev) => new Set([...prev, currentStep]));
setCurrentStep((prev) => Math.min(prev + 1, steps.length - 1));
}, [currentStep, validateStep]);
const handleBack = useCallback(() => {
setCurrentStep((prev) => Math.max(prev - 1, 0));
}, []);
Field rendering per step
const currentGroup = stepGroups[currentStep];
const currentFields = {};
if (currentGroup) {
const fieldNames = stepFields[steps[currentStep].key] || [];
fieldNames.forEach((name) => {
currentFields[name] = currentGroup.$(name);
});
}
// Render:
Step indicator
{steps.map((s, i) => (
isCompleted && onGoTo(i)}
disabled={!isCompleted}
className={i === currentStep ? 'active' : ''}
>
{completedSteps.has(i) ? : i + 1}
{s.label}
))}
Review screen
const step1 = form.$('step1');
const step2 = form.$('step2');
const step3 = form.$('step3');
Final submission
const handleSubmit = useCallback(async () => {
let allValid = true;
for (let i = 0; i new Set([...prev, i]));
if (!valid) allValid = false;
}
if (allValid) {
await form.submit();
setSubmitted(true);
}
}, [validateStep, stepGroups, form]);
Handling File Fields in Steps
File fields can be included in any step:
const fields = [
'step1.firstName',
'step1.avatar', // file field
'step2.documents', // file field
];
Nested Composition Alternative
For completely independent forms (different submit endpoints), see the [mobx-react-form-composer](../mobx-react-form-composer/SKILL.md) pattern instead of a single multi-step form.
Key Takeaways
- Nested groups: Each step is a dot-notation group (
step1.*,step2.*) in the same form. - Per-step validation: Use
group.validate()to validate only the current step. - Gate navigation: Check
group.isValidto decide whether to advance. - Track completion: Use a
Setof step indices for visual state. - Persist data: Previous steps' values remain in the form — review step reads them directly.
- Final validation: Re-validate all steps at submission to catch changes from revisiting.
Related Skills
- [mobx-react-form-api](../mobx-react-form-api/SKILL.md) — Core API prerequisite
- [mobx-react-form-nested](../mobx-react-form-nested/SKILL.md) — Nested fields for step groups
- [mobx-react-form-validation](../mobx-react-form-validation/SKILL.md) — Per-step validation
- [mobx-react-form-composer](../mobx-react-form-composer/SKILL.md) — Alternative: multiple independent forms
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: foxhound87
- Source: foxhound87/skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.