react-declarative-docs / documents /docs_components_wizard.html
tripolskypetr's picture
patch
9375fc1
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>docs/components/wizard | react-declarative</title><meta name="description" content="Documentation for react-declarative"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script><script async src="../assets/hierarchy.js" id="tsd-hierarchy-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">react-declarative</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">react-declarative</a></li><li><a href="docs_components_wizard.html">docs/components/wizard</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="wizardview-multi-step-forms-with-mui-stepper-routing" class="tsd-anchor"></a><h1 class="tsd-anchor-link">WizardView: multi-step forms with MUI Stepper routing<a href="#wizardview-multi-step-forms-with-mui-stepper-routing" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h1><p><code>&lt;WizardView /&gt;</code> combines a Material UI stepper with a nested router outlet, letting you build multi-step flows where each step is a full page component. You define steps as <code>IWizardStep[]</code> (what appears in the stepper) and routes as <code>IWizardOutlet[]</code> (which component renders when a given path is active). Navigation between steps is done programmatically via <code>history.replace()</code> so deep-linking and browser Back work out of the box.</p>
<a id="installation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Installation<a href="#installation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><pre><code class="bash"><span class="hl-5">npm</span><span class="hl-1"> </span><span class="hl-3">install</span><span class="hl-1"> </span><span class="hl-4">--save</span><span class="hl-1"> </span><span class="hl-3">react-declarative</span><span class="hl-1"> </span><span class="hl-3">tss-react</span><span class="hl-1"> </span><span class="hl-3">@mui/material</span><span class="hl-1"> </span><span class="hl-3">@emotion/react</span><span class="hl-1"> </span><span class="hl-3">@emotion/styled</span>
</code><button type="button">Copy</button></pre>
<a id="complete-example" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Complete example<a href="#complete-example" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><a id="step-1-define-your-steps-and-routes" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Step 1: Define your steps and routes<a href="#step-1-define-your-steps-and-routes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Steps appear in the stepper header. Routes map URL paths to step components.</p>
<pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">IWizardStep</span><span class="hl-1">, </span><span class="hl-2">IWizardOutlet</span><span class="hl-1">, </span><span class="hl-2">parseRouteUrl</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;react-declarative&#39;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">SelectFileView</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;./steps/SelectFileView&#39;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">ValidateFileView</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;./steps/ValidateFileView&#39;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">ImportFileView</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;./steps/ImportFileView&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">steps</span><span class="hl-1">: </span><span class="hl-7">IWizardStep</span><span class="hl-1">[] = [</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;select&#39;</span><span class="hl-1">, </span><span class="hl-2">label:</span><span class="hl-1"> </span><span class="hl-3">&#39;Choose file&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;validate&#39;</span><span class="hl-1">, </span><span class="hl-2">label:</span><span class="hl-1"> </span><span class="hl-3">&#39;Validation&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;import&#39;</span><span class="hl-1">, </span><span class="hl-2">label:</span><span class="hl-1"> </span><span class="hl-3">&#39;Import&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">routes</span><span class="hl-1">: </span><span class="hl-7">IWizardOutlet</span><span class="hl-1">[] = [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;select&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">SelectFileView</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isActive</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">pathname</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> !!</span><span class="hl-5">parseRouteUrl</span><span class="hl-1">(</span><span class="hl-3">&#39;/select-file&#39;</span><span class="hl-1">, </span><span class="hl-2">pathname</span><span class="hl-1">),</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;validate&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">ValidateFileView</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isActive</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">pathname</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> !!</span><span class="hl-5">parseRouteUrl</span><span class="hl-1">(</span><span class="hl-3">&#39;/validate-file&#39;</span><span class="hl-1">, </span><span class="hl-2">pathname</span><span class="hl-1">),</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;import&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">element:</span><span class="hl-1"> </span><span class="hl-2">ImportFileView</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isActive</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">pathname</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> !!</span><span class="hl-5">parseRouteUrl</span><span class="hl-1">(</span><span class="hl-3">&#39;/import-file&#39;</span><span class="hl-1">, </span><span class="hl-2">pathname</span><span class="hl-1">),</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">];</span>
</code><button type="button">Copy</button></pre>
<a id="step-2-render-wizardview" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Step 2: Render WizardView<a href="#step-2-render-wizardview" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Pass <code>steps</code>, <code>routes</code>, and the current <code>pathname</code>. The wizard activates
whichever outlet's <code>isActive</code> returns <code>true</code> for the given path.</p>
<pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">WizardView</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;react-declarative&#39;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">steps</span><span class="hl-1">, </span><span class="hl-2">routes</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;./wizard-config&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">ImportWizard</span><span class="hl-1"> = () </span><span class="hl-4">=&gt;</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</span><span class="hl-7">WizardView</span><br/><span class="hl-1"> </span><span class="hl-8">pathname</span><span class="hl-1">=</span><span class="hl-3">&quot;/select-file&quot;</span><br/><span class="hl-1"> </span><span class="hl-8">steps</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">steps</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">routes</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">routes</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">/&gt;</span><br/><span class="hl-1">);</span>
</code><button type="button">Copy</button></pre>
<a id="step-3-implement-each-step-component" class="tsd-anchor"></a><h3 class="tsd-anchor-link">Step 3: Implement each step component<a href="#step-3-implement-each-step-component" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><p>Each outlet element receives <code>IWizardOutletProps</code> which includes a
<code>history</code> object for programmatic navigation. Wrap your content in
<code>WizardContainer</code> and pass a <code>WizardNavigation</code> to the <code>Navigation</code> slot.</p>
<pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">WizardContainer</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">WizardNavigation</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">IWizardOutletProps</span><span class="hl-1">,</span><br/><span class="hl-1">} </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;react-declarative&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">SelectFileView</span><span class="hl-1"> = ({ </span><span class="hl-2">history</span><span class="hl-1"> }: </span><span class="hl-7">IWizardOutletProps</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> [</span><span class="hl-10">file</span><span class="hl-1">, </span><span class="hl-10">setFile</span><span class="hl-1">] = </span><span class="hl-2">React</span><span class="hl-1">.</span><span class="hl-5">useState</span><span class="hl-1">&lt;</span><span class="hl-7">File</span><span class="hl-1"> | </span><span class="hl-7">null</span><span class="hl-1">&gt;(</span><span class="hl-4">null</span><span class="hl-1">);</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</span><span class="hl-7">WizardContainer</span><br/><span class="hl-1"> </span><span class="hl-8">Navigation</span><span class="hl-1">=</span><span class="hl-4">{</span><br/><span class="hl-9"> </span><span class="hl-6">&lt;</span><span class="hl-7">WizardNavigation</span><br/><span class="hl-9"> </span><span class="hl-8">hasNext</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-1">!!</span><span class="hl-2">file</span><span class="hl-4">}</span><br/><span class="hl-9"> </span><span class="hl-8">onNext</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-9">() </span><span class="hl-4">=&gt;</span><span class="hl-9"> </span><span class="hl-2">history</span><span class="hl-9">.</span><span class="hl-5">replace</span><span class="hl-9">(</span><span class="hl-3">&#39;/validate-file&#39;</span><span class="hl-9">)</span><span class="hl-4">}</span><br/><span class="hl-9"> </span><span class="hl-6">/&gt;</span><br/><span class="hl-9"> </span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</span><span class="hl-18">input</span><br/><span class="hl-1"> </span><span class="hl-8">type</span><span class="hl-1">=</span><span class="hl-3">&quot;file&quot;</span><br/><span class="hl-1"> </span><span class="hl-8">onChange</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-9">(</span><span class="hl-2">e</span><span class="hl-9">) </span><span class="hl-4">=&gt;</span><span class="hl-9"> </span><span class="hl-5">setFile</span><span class="hl-9">(</span><span class="hl-2">e</span><span class="hl-9">.</span><span class="hl-2">target</span><span class="hl-9">.</span><span class="hl-2">files</span><span class="hl-9">?.[</span><span class="hl-16">0</span><span class="hl-9">] </span><span class="hl-1">??</span><span class="hl-9"> </span><span class="hl-4">null</span><span class="hl-9">)</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">/&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/</span><span class="hl-7">WizardContainer</span><span class="hl-6">&gt;</span><br/><span class="hl-1"> );</span><br/><span class="hl-1">};</span>
</code><button type="button">Copy</button></pre>
<pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">WizardContainer</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">WizardNavigation</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">IWizardOutletProps</span><span class="hl-1">,</span><br/><span class="hl-1">} </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;react-declarative&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">ValidateFileView</span><span class="hl-1"> = ({ </span><span class="hl-2">history</span><span class="hl-1"> }: </span><span class="hl-7">IWizardOutletProps</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</span><span class="hl-7">WizardContainer</span><br/><span class="hl-1"> </span><span class="hl-8">Navigation</span><span class="hl-1">=</span><span class="hl-4">{</span><br/><span class="hl-9"> </span><span class="hl-6">&lt;</span><span class="hl-7">WizardNavigation</span><br/><span class="hl-9"> </span><span class="hl-8">hasPrev</span><br/><span class="hl-9"> </span><span class="hl-8">hasNext</span><br/><span class="hl-9"> </span><span class="hl-8">onPrev</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-9">() </span><span class="hl-4">=&gt;</span><span class="hl-9"> </span><span class="hl-2">history</span><span class="hl-9">.</span><span class="hl-5">replace</span><span class="hl-9">(</span><span class="hl-3">&#39;/select-file&#39;</span><span class="hl-9">)</span><span class="hl-4">}</span><br/><span class="hl-9"> </span><span class="hl-8">onNext</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-9">() </span><span class="hl-4">=&gt;</span><span class="hl-9"> </span><span class="hl-2">history</span><span class="hl-9">.</span><span class="hl-5">replace</span><span class="hl-9">(</span><span class="hl-3">&#39;/import-file&#39;</span><span class="hl-9">)</span><span class="hl-4">}</span><br/><span class="hl-9"> </span><span class="hl-6">/&gt;</span><br/><span class="hl-9"> </span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</span><span class="hl-18">p</span><span class="hl-6">&gt;</span><span class="hl-1">Validating your file…</span><span class="hl-6">&lt;/</span><span class="hl-18">p</span><span class="hl-6">&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/</span><span class="hl-7">WizardContainer</span><span class="hl-6">&gt;</span><br/><span class="hl-1">);</span>
</code><button type="button">Copy</button></pre>
<a id="key-props--wizardview" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Key props — <code>WizardView</code><a href="#key-props--wizardview" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p><strong><code>steps</code></strong><code>IWizardStep[]</code> (required)</p>
<p>The ordered list of steps shown in the MUI Stepper header. Each step has an
<code>id</code>, an optional <code>label</code>, and an optional <code>icon</code>.</p>
<hr>
<p><strong><code>routes</code></strong><code>IWizardOutlet[]</code> (required)</p>
<p>Maps URL pathnames to step components. Each outlet's <code>isActive</code> function
receives the current <code>pathname</code> and returns <code>true</code> when that step should
render.</p>
<hr>
<p><strong><code>pathname</code></strong><code>string</code></p>
<p>The currently active path. When you manage routing externally (e.g. React
Router), sync this prop from <code>location.pathname</code>. If omitted, the wizard
manages its own internal history.</p>
<hr>
<p><strong><code>history</code></strong><code>History</code></p>
<p>A custom history object. Pass your router's history instance to integrate
with React Router or a similar library.</p>
<hr>
<p><strong><code>onNavigate</code></strong><code>(update: Update) =&gt; void</code></p>
<p>Called whenever the wizard's internal history changes. Use this to sync the
browser URL when running the wizard inside a larger router.</p>
<hr>
<p><strong><code>withScroll</code></strong><code>boolean</code></p>
<p>Wraps the step content in a scrollable container. Useful for long-form step
views that might exceed the viewport height.</p>
<hr>
<p><strong><code>outlinePaper</code></strong><code>boolean</code></p>
<p>Renders the step content area with an outlined paper background rather than
elevated.</p>
<a id="wizardnavigation-props" class="tsd-anchor"></a><h2 class="tsd-anchor-link"><code>WizardNavigation</code> props<a href="#wizardnavigation-props" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p><code>WizardNavigation</code> renders the Prev / Next button row. Place it in the
<code>Navigation</code> slot of <code>WizardContainer</code>.</p>
<p><strong><code>hasPrev</code></strong><code>boolean</code></p>
<p>Enables the Prev button. Pass <code>false</code> (default) on the first step.</p>
<hr>
<p><strong><code>hasNext</code></strong><code>boolean</code></p>
<p>Enables the Next button. Pass <code>false</code> (default) on the last step, or when
the step's required input is not yet complete.</p>
<hr>
<p><strong><code>onPrev</code></strong><code>() =&gt; void | Promise&lt;void&gt;</code></p>
<p>Called when the user clicks Prev. Call <code>history.replace('/previous-path')</code>
inside this handler.</p>
<hr>
<p><strong><code>onNext</code></strong><code>() =&gt; void | Promise&lt;void&gt;</code></p>
<p>Called when the user clicks Next. Can be async — the button shows a loading
indicator while the promise is pending and prevents double-clicks.</p>
<hr>
<p><strong><code>labelPrev</code></strong><code>string</code></p>
<p>Label for the Prev button. Defaults to <code>&quot;Prev&quot;</code>.</p>
<hr>
<p><strong><code>labelNext</code></strong><code>string</code></p>
<p>Label for the Next button. Defaults to <code>&quot;Next&quot;</code>.</p>
<a id="programmatic-navigation" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Programmatic navigation<a href="#programmatic-navigation" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Each outlet component receives a <code>history</code> object in its props. Call
<code>history.replace()</code> to move between steps without adding an entry to the
browser history stack, or <code>history.push()</code> to allow the user to go Back:</p>
<pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">IWizardOutletProps</span><span class="hl-1">, </span><span class="hl-2">WizardContainer</span><span class="hl-1">, </span><span class="hl-2">WizardNavigation</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;react-declarative&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">StepOne</span><span class="hl-1"> = ({ </span><span class="hl-2">history</span><span class="hl-1"> }: </span><span class="hl-7">IWizardOutletProps</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">handleNext</span><span class="hl-1"> = </span><span class="hl-4">async</span><span class="hl-1"> () </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-17">// Perform async validation before advancing</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">ok</span><span class="hl-1"> = </span><span class="hl-0">await</span><span class="hl-1"> </span><span class="hl-5">validateStep</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-0">if</span><span class="hl-1"> (</span><span class="hl-2">ok</span><span class="hl-1">) {</span><br/><span class="hl-1"> </span><span class="hl-2">history</span><span class="hl-1">.</span><span class="hl-5">replace</span><span class="hl-1">(</span><span class="hl-3">&#39;/step-two&#39;</span><span class="hl-1">);</span><br/><span class="hl-1"> }</span><br/><span class="hl-1"> };</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</span><span class="hl-7">WizardContainer</span><br/><span class="hl-1"> </span><span class="hl-8">Navigation</span><span class="hl-1">=</span><span class="hl-4">{</span><br/><span class="hl-9"> </span><span class="hl-6">&lt;</span><span class="hl-7">WizardNavigation</span><br/><span class="hl-9"> </span><span class="hl-8">hasNext</span><br/><span class="hl-9"> </span><span class="hl-8">onNext</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">handleNext</span><span class="hl-4">}</span><br/><span class="hl-9"> </span><span class="hl-8">labelNext</span><span class="hl-1">=</span><span class="hl-3">&quot;Validate &amp; continue&quot;</span><br/><span class="hl-9"> </span><span class="hl-6">/&gt;</span><br/><span class="hl-9"> </span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</span><span class="hl-7">StepOneForm</span><span class="hl-1"> </span><span class="hl-6">/&gt;</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;/</span><span class="hl-7">WizardContainer</span><span class="hl-6">&gt;</span><br/><span class="hl-1"> );</span><br/><span class="hl-1">};</span>
</code><button type="button">Copy</button></pre>
<a id="conditional-step-visibility" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Conditional step visibility<a href="#conditional-step-visibility" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>Use <code>isVisible</code> on an <code>IWizardStep</code> to hide steps from the stepper header
based on your payload (e.g. user role or previous step choices):</p>
<pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">IWizardStep</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;react-declarative&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-4">interface</span><span class="hl-1"> </span><span class="hl-7">IWizardPayload</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">needsApproval</span><span class="hl-1">: </span><span class="hl-7">boolean</span><span class="hl-1">;</span><br/><span class="hl-1">}</span><br/><br/><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">steps</span><span class="hl-1">: </span><span class="hl-7">IWizardStep</span><span class="hl-1">&lt;</span><span class="hl-7">IWizardPayload</span><span class="hl-1">&gt;[] = [</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;details&#39;</span><span class="hl-1">, </span><span class="hl-2">label:</span><span class="hl-1"> </span><span class="hl-3">&#39;Details&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;approval&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">label:</span><span class="hl-1"> </span><span class="hl-3">&#39;Approval&#39;</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isVisible</span><span class="hl-2">:</span><span class="hl-1"> (</span><span class="hl-2">payload</span><span class="hl-1">) </span><span class="hl-4">=&gt;</span><span class="hl-1"> </span><span class="hl-2">payload</span><span class="hl-1">.</span><span class="hl-2">needsApproval</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> { </span><span class="hl-2">id:</span><span class="hl-1"> </span><span class="hl-3">&#39;confirm&#39;</span><span class="hl-1">, </span><span class="hl-2">label:</span><span class="hl-1"> </span><span class="hl-3">&#39;Confirm&#39;</span><span class="hl-1"> },</span><br/><span class="hl-1">];</span>
</code><button type="button">Copy</button></pre>
<blockquote>
<p><strong>Note:</strong> Hiding a step with <code>isVisible</code> removes it from the stepper UI but does not
prevent navigation to its route. Guard the corresponding outlet component if
you want to block direct URL access.</p>
</blockquote>
<a id="nested-routing-integration" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Nested routing integration<a href="#nested-routing-integration" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h2><p>When embedding <code>WizardView</code> inside an existing React Router setup, pass your
router's <code>history</code> instance and listen to <code>onNavigate</code> to keep the browser URL
in sync:</p>
<pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">useHistory</span><span class="hl-1">, </span><span class="hl-2">useLocation</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;react-router-dom&#39;</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">WizardView</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">&#39;react-declarative&#39;</span><span class="hl-1">;</span><br/><br/><span class="hl-0">export</span><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-5">ImportWizardPage</span><span class="hl-1"> = () </span><span class="hl-4">=&gt;</span><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">history</span><span class="hl-1"> = </span><span class="hl-5">useHistory</span><span class="hl-1">();</span><br/><span class="hl-1"> </span><span class="hl-4">const</span><span class="hl-1"> </span><span class="hl-10">location</span><span class="hl-1"> = </span><span class="hl-5">useLocation</span><span class="hl-1">();</span><br/><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6">&lt;</span><span class="hl-7">WizardView</span><br/><span class="hl-1"> </span><span class="hl-8">pathname</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">location</span><span class="hl-9">.</span><span class="hl-2">pathname</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">history</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">history</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">onNavigate</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-9">({ </span><span class="hl-2">location</span><span class="hl-9">: </span><span class="hl-2">next</span><span class="hl-9"> }) </span><span class="hl-4">=&gt;</span><span class="hl-9"> {</span><br/><span class="hl-9"> </span><span class="hl-2">history</span><span class="hl-9">.</span><span class="hl-5">replace</span><span class="hl-9">(</span><span class="hl-2">next</span><span class="hl-9">.</span><span class="hl-2">pathname</span><span class="hl-9">);</span><br/><span class="hl-9"> }</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">steps</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">steps</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">routes</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">routes</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">/&gt;</span><br/><span class="hl-1"> );</span><br/><span class="hl-1">};</span>
</code><button type="button">Copy</button></pre>
<blockquote>
<p><strong>Tip:</strong> Keep step URLs under a shared prefix (e.g. <code>/import/select-file</code>,
<code>/import/validate-file</code>) so that a single React Router <code>&lt;Route path=&quot;/import/*&quot; /&gt;</code>
renders the wizard without interfering with other pages.</p>
</blockquote>
</div></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><a href="#wizardview-multi-step-forms-with-mui-stepper-routing"><span>Wizard<wbr/>View: multi-<wbr/>step forms with MUI <wbr/>Stepper routing</span></a><ul><li><a href="#installation"><span>Installation</span></a></li><li><a href="#complete-example"><span>Complete example</span></a></li><li><ul><li><a href="#step-1-define-your-steps-and-routes"><span>Step 1: <wbr/>Define your steps and routes</span></a></li><li><a href="#step-2-render-wizardview"><span>Step 2: <wbr/>Render <wbr/>Wizard<wbr/>View</span></a></li><li><a href="#step-3-implement-each-step-component"><span>Step 3: <wbr/>Implement each step component</span></a></li></ul></li><li><a href="#key-props--wizardview"><span>Key props — <wbr/>Wizard<wbr/>View</span></a></li><li><a href="#wizardnavigation-props"><span>Wizard<wbr/>Navigation props</span></a></li><li><a href="#programmatic-navigation"><span>Programmatic navigation</span></a></li><li><a href="#conditional-step-visibility"><span>Conditional step visibility</span></a></li><li><a href="#nested-routing-integration"><span>Nested routing integration</span></a></li></ul></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">react-declarative</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>