| <!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/advanced/ai-integration | 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_advanced_ai-integration.html">docs/advanced/ai-integration</a></li></ul></div><div class="tsd-panel tsd-typography"><a id="generating-ui-with-ai-using-json-schemas" class="tsd-anchor"></a><h1 class="tsd-anchor-link">Generating UI with AI using JSON schemas<a href="#generating-ui-with-ai-using-json-schemas" 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>react-declarative</code> is exceptionally well-suited for AI-assisted UI generation. The form schema is a plain JSON array of field objectsβno JSX, no hooks, no state management code. Because <code><One /></code> handles all state automatically, you never need to ask an AI to write <code>useState</code>, <code>useEffect</code>, or event handlers. You give the model a working example, describe what you want, and paste the output directly into the playground to verify it before using it in your app.</p> |
| <a id="try-it-in-the-playground-first" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Try it in the playground first<a href="#try-it-in-the-playground-first" 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>Before writing any code, try generating schemas at <a href="https://react-declarative-playground.github.io/">react-declarative-playground.github.io</a>. The playground runs entirely in the browserβpaste a schema and see the rendered form immediately.</p> |
| <blockquote> |
| <p><strong>Tip:</strong> The playground accepts the raw <code>fields</code> array. You do not need a full React componentβjust the JSON.</p> |
| </blockquote> |
| <a id="why-llms-work-well-with-this-format" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Why LLMs work well with this format<a href="#why-llms-work-well-with-this-format" 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>The <code>IField</code> / <code>TypedField</code> schema has properties that are self-describing:</p> |
| <ul> |
| <li><code>type</code> is a string enum (<code>FieldType.Text</code>, <code>FieldType.Combo</code>, etc.)βeasy to enumerate in a prompt</li> |
| <li><code>name</code> maps directly to a data field nameβno wiring needed</li> |
| <li><code>isVisible</code>, <code>isDisabled</code>, <code>isInvalid</code> are plain functionsβLLMs write them naturally</li> |
| <li>Layout is expressed as <code>columns</code> strings (<code>"6"</code> = half-width)βno CSS to invent</li> |
| <li>Validation lives inside the schema, not in a separate schema file</li> |
| </ul> |
| <p>Because state management is automatic, the AI never needs to generate any React state code. The complete output is just a <code>TypedField[]</code> array.</p> |
| <a id="the-prompt-workflow" class="tsd-anchor"></a><h2 class="tsd-anchor-link">The prompt workflow<a href="#the-prompt-workflow" 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>Step 1: Choose a reference sample</strong></p> |
| <p>Pick a sample schema from the list below that most closely resembles what you want to build. Copy the entire code block including the <code>import</code> line.</p> |
| <p><strong>Step 2: Open your preferred AI tool</strong></p> |
| <p>Any major LLM works. ChatGPT, Claude, Gemini, Copilot, and Perplexity all have enough knowledge of <code>react-declarative</code> to generate valid schemas.</p> |
| <p><strong>Step 3: Send the reference + your description</strong></p> |
| <p>Paste the sample code into the chat and add your request. A reliable prompt pattern:</p> |
| <pre><code class="text">Read the code below and generate a new form schema in the same format. |
| The form should collect: [describe your fields here]. |
|
|
| [paste the sample code] |
| </code><button type="button">Copy</button></pre> |
|
|
| <p><strong>Step 4: Verify in the playground</strong></p> |
| <p>Copy the generated <code>fields</code> array to <a href="https://react-declarative-playground.github.io/">react-declarative-playground.github.io</a> and check the rendered output. Fix any issues by asking the AI to adjust.</p> |
| <p><strong>Step 5: Drop it into your app</strong></p> |
| <p>Once it looks right, import the fields array and pass it to <code><One /></code>.</p> |
| <pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">One</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">"react-declarative"</span><span class="hl-1">;</span><br/><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">fields</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">"./generatedFields"</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">MyPage</span><span class="hl-1"> = () </span><span class="hl-4">=></span><span class="hl-1"> (</span><br/><span class="hl-1"> </span><span class="hl-6"><</span><span class="hl-7">One</span><br/><span class="hl-1"> </span><span class="hl-8">fields</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-2">fields</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-8">handler</span><span class="hl-1">=</span><span class="hl-4">{</span><span class="hl-9">() </span><span class="hl-4">=></span><span class="hl-9"> ({})</span><span class="hl-4">}</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">data</span><span class="hl-9">) </span><span class="hl-4">=></span><span class="hl-9"> </span><span class="hl-2">console</span><span class="hl-9">.</span><span class="hl-5">log</span><span class="hl-9">(</span><span class="hl-2">data</span><span class="hl-9">)</span><span class="hl-4">}</span><br/><span class="hl-1"> </span><span class="hl-6">/></span><br/><span class="hl-1">);</span> |
| </code><button type="button">Copy</button></pre> |
|
|
| <a id="reference-samples" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Reference samples<a href="#reference-samples" 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>These samples exist specifically as AI training material. Each one demonstrates a different combination of field types, layouts, and validation patterns.</p> |
| <a id="order_info--multi-section-form-with-date-and-combo-fields" class="tsd-anchor"></a><h3 class="tsd-anchor-link">order_info β multi-section form with date and combo fields<a href="#order_info--multi-section-form-with-date-and-combo-fields" 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>A three-section form covering general information, passport details, and profile metadata. Demonstrates <code>FieldType.Paper</code> grouping, responsive column layout, and <code>FieldType.Date</code> / <code>FieldType.Combo</code> usage.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/order_info.md">docs/sample/order_info.md</a></p> |
| <a id="login_form--centered-card-with-action-feedback" class="tsd-anchor"></a><h3 class="tsd-anchor-link">login_form β centered card with action feedback<a href="#login_form--centered-card-with-action-feedback" 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>A sign-in form centered in the viewport using <code>FieldType.Box</code> and <code>FieldType.Paper</code>, with a <code>Subject</code>-driven loading state on the submit icon. Good reference for action-button patterns.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/login_form.md">docs/sample/login_form.md</a></p> |
| <a id="profile_card--avatar-layout-with-nested-groups" class="tsd-anchor"></a><h3 class="tsd-anchor-link">profile_card β avatar layout with nested groups<a href="#profile_card--avatar-layout-with-nested-groups" 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>A profile page with a CSS-grid avatar section, inline conditional fields, <code>FieldType.Expansion</code> for collapsible areas, and email validation. Demonstrates <code>FieldType.Component</code> for embedding arbitrary JSX.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/profile_card.md">docs/sample/profile_card.md</a></p> |
| <a id="settings_page--grouped-settings-with-switches-and-sliders" class="tsd-anchor"></a><h3 class="tsd-anchor-link">settings_page β grouped settings with switches and sliders<a href="#settings_page--grouped-settings-with-switches-and-sliders" 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>A settings page using <code>FieldType.Switch</code>, <code>FieldType.Slider</code>, <code>FieldType.Rating</code>, and <code>FieldType.Progress</code>. Good for AI to learn the full range of input types.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/settings_page.md">docs/sample/settings_page.md</a></p> |
| <a id="gallery_of_controls--one-of-every-field-type" class="tsd-anchor"></a><h3 class="tsd-anchor-link">gallery_of_controls β one of every field type<a href="#gallery_of_controls--one-of-every-field-type" 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>Every available <code>FieldType</code> in a single form. Use this sample when you want the AI to know the complete vocabulary of available field types.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/gallery_of_controls.md">docs/sample/gallery_of_controls.md</a></p> |
| <a id="typography--display-only-content-layouts" class="tsd-anchor"></a><h3 class="tsd-anchor-link">typography β display-only content layouts<a href="#typography--display-only-content-layouts" 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>Forms that combine <code>FieldType.Typography</code>, <code>FieldType.Line</code>, and <code>FieldType.Rating</code> to create read-only display panels. Good for dashboards and detail views.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/typography.md">docs/sample/typography.md</a></p> |
| <a id="product_shape--e-commerce-product-form" class="tsd-anchor"></a><h3 class="tsd-anchor-link">product_shape β e-commerce product form<a href="#product_shape--e-commerce-product-form" 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>A product entry form with price, SKU, category combo, stock toggle, and image URL. Demonstrates mixed outlined and standard field variants.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/product_shape.md">docs/sample/product_shape.md</a></p> |
| <a id="variant_form--conditional-field-visibility" class="tsd-anchor"></a><h3 class="tsd-anchor-link">variant_form β conditional field visibility<a href="#variant_form--conditional-field-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></h3><p>A form where fields appear and disappear based on other field values using <code>isVisible</code>. The best sample for showing the AI how conditional logic works.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/variant_form.md">docs/sample/variant_form.md</a></p> |
| <a id="adaptive_form--responsive-multi-column-layout" class="tsd-anchor"></a><h3 class="tsd-anchor-link">adaptive_form β responsive multi-column layout<a href="#adaptive_form--responsive-multi-column-layout" 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>A form that uses <code>desktopColumns</code>, <code>tabletColumns</code>, and <code>phoneColumns</code> on every field. Use this when you need the AI to generate a layout that works on multiple screen sizes.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/adaptive_form.md">docs/sample/adaptive_form.md</a></p> |
| <a id="dashboard--kpi-cards-and-data-display" class="tsd-anchor"></a><h3 class="tsd-anchor-link">dashboard β KPI cards and data display<a href="#dashboard--kpi-cards-and-data-display" 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>A read-only dashboard layout using nested <code>FieldType.Paper</code> and <code>FieldType.Group</code> containers with <code>FieldType.Component</code> cells. Good for report-style UIs.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/dashboard.md">docs/sample/dashboard.md</a></p> |
| <a id="account_info--account-management-form" class="tsd-anchor"></a><h3 class="tsd-anchor-link">account_info β account management form<a href="#account_info--account-management-form" 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>A full account settings page with personal details, password change, and notification preferences sections.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/account_info.md">docs/sample/account_info.md</a></p> |
| <a id="custom_jsx--arbitrary-jsx-inside-a-form" class="tsd-anchor"></a><h3 class="tsd-anchor-link">custom_jsx β arbitrary JSX inside a form<a href="#custom_jsx--arbitrary-jsx-inside-a-form" 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>Demonstrates <code>FieldType.Component</code> and <code>FieldType.Layout</code> for embedding completely custom React components inside a <code><One /></code> form without breaking the state model.</p> |
| <p>See <a href="https://github.com/react-declarative/react-declarative/blob/master/docs/sample/custom_jsx.md">docs/sample/custom_jsx.md</a></p> |
| <a id="example-generating-a-registration-form" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Example: generating a registration form<a href="#example-generating-a-registration-form" 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>Here is a concrete prompt and the kind of output it produces.</p> |
| <p><strong>Prompt:</strong></p> |
| <pre><code class="text">Read the code below and generate a new form schema in the same format. |
|
|
| The form should collect user registration data: |
| - First name and last name (side by side, required) |
| - Email address (with validation) |
| - Password and confirm password (with match validation) |
| - Date of birth |
| - Country (dropdown: USA, UK, Canada, Australia) |
| - Terms accepted (checkbox, required) |
|
|
| Use FieldType.Paper to group related fields. |
| Show validation errors only after the field has been touched. |
|
|
| [paste the order_info.md code here] |
| </code><button type="button">Copy</button></pre> |
|
|
| <p><strong>Generated output:</strong></p> |
| <pre><code class="tsx"><span class="hl-0">import</span><span class="hl-1"> { </span><span class="hl-2">TypedField</span><span class="hl-1">, </span><span class="hl-2">FieldType</span><span class="hl-1"> } </span><span class="hl-0">from</span><span class="hl-1"> </span><span class="hl-3">"react-declarative"</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">fields</span><span class="hl-1">: </span><span class="hl-7">TypedField</span><span class="hl-1">[] = [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Paper</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">fieldBottomMargin:</span><span class="hl-1"> </span><span class="hl-3">"1"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">fields:</span><span class="hl-1"> [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Typography</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">typoVariant:</span><span class="hl-1"> </span><span class="hl-3">"h6"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">placeholder:</span><span class="hl-1"> </span><span class="hl-3">"Personal Information"</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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Text</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">desktopColumns:</span><span class="hl-1"> </span><span class="hl-3">"6"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">tabletColumns:</span><span class="hl-1"> </span><span class="hl-3">"6"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">phoneColumns:</span><span class="hl-1"> </span><span class="hl-3">"12"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">outlined:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">"firstName"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">"First Name"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isInvalid</span><span class="hl-2">:</span><span class="hl-1"> ({ </span><span class="hl-2">firstName</span><span class="hl-1"> }) </span><span class="hl-4">=></span><br/><span class="hl-1"> !</span><span class="hl-2">firstName</span><span class="hl-1"> ? </span><span class="hl-3">"First name is required"</span><span class="hl-1"> : </span><span class="hl-4">null</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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Text</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">desktopColumns:</span><span class="hl-1"> </span><span class="hl-3">"6"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">tabletColumns:</span><span class="hl-1"> </span><span class="hl-3">"6"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">phoneColumns:</span><span class="hl-1"> </span><span class="hl-3">"12"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">outlined:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">"lastName"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">"Last Name"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isInvalid</span><span class="hl-2">:</span><span class="hl-1"> ({ </span><span class="hl-2">lastName</span><span class="hl-1"> }) </span><span class="hl-4">=></span><br/><span class="hl-1"> !</span><span class="hl-2">lastName</span><span class="hl-1"> ? </span><span class="hl-3">"Last name is required"</span><span class="hl-1"> : </span><span class="hl-4">null</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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Text</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">outlined:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">"email"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">"Email Address"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isInvalid</span><span class="hl-2">:</span><span class="hl-1"> ({ </span><span class="hl-2">email</span><span class="hl-1"> }) </span><span class="hl-4">=></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">re</span><span class="hl-1"> =</span><span class="hl-11"> /</span><span class="hl-12">^</span><span class="hl-13">[</span><span class="hl-14">\w</span><span class="hl-11">-.</span><span class="hl-13">]</span><span class="hl-15">+</span><span class="hl-11">@</span><span class="hl-13">([</span><span class="hl-11">\w-</span><span class="hl-13">]</span><span class="hl-15">+</span><span class="hl-14">\.</span><span class="hl-13">)</span><span class="hl-15">+</span><span class="hl-13">[</span><span class="hl-11">\w-</span><span class="hl-13">]</span><span class="hl-15">{2,4}</span><span class="hl-12">$</span><span class="hl-11">/</span><span class="hl-1">;</span><br/><span class="hl-1"> </span><span class="hl-0">return</span><span class="hl-1"> </span><span class="hl-2">re</span><span class="hl-1">.</span><span class="hl-5">test</span><span class="hl-1">(</span><span class="hl-2">email</span><span class="hl-1">) ? </span><span class="hl-4">null</span><span class="hl-1"> : </span><span class="hl-3">"Enter a valid email address"</span><span class="hl-1">;</span><br/><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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Date</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">outlined:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">"dateOfBirth"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">"Date of Birth"</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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Combo</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">outlined:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">"country"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">"Country"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">itemList:</span><span class="hl-1"> [</span><span class="hl-3">"USA"</span><span class="hl-1">, </span><span class="hl-3">"UK"</span><span class="hl-1">, </span><span class="hl-3">"Canada"</span><span class="hl-1">, </span><span class="hl-3">"Australia"</span><span class="hl-1">],</span><br/><span class="hl-1"> },</span><br/><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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Paper</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">fieldBottomMargin:</span><span class="hl-1"> </span><span class="hl-3">"1"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">fields:</span><span class="hl-1"> [</span><br/><span class="hl-1"> {</span><br/><span class="hl-1"> </span><span class="hl-2">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Typography</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">typoVariant:</span><span class="hl-1"> </span><span class="hl-3">"h6"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">placeholder:</span><span class="hl-1"> </span><span class="hl-3">"Password"</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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Text</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">outlined:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">"password"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">"Password"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">inputType:</span><span class="hl-1"> </span><span class="hl-3">"password"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isInvalid</span><span class="hl-2">:</span><span class="hl-1"> ({ </span><span class="hl-2">password</span><span class="hl-1"> }) </span><span class="hl-4">=></span><br/><span class="hl-1"> </span><span class="hl-2">password</span><span class="hl-1"> && </span><span class="hl-2">password</span><span class="hl-1">.</span><span class="hl-2">length</span><span class="hl-1"> >= </span><span class="hl-16">8</span><br/><span class="hl-1"> ? </span><span class="hl-4">null</span><br/><span class="hl-1"> : </span><span class="hl-3">"Password must be at least 8 characters"</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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">Text</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">outlined:</span><span class="hl-1"> </span><span class="hl-4">true</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">"confirmPassword"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">"Confirm Password"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">inputType:</span><span class="hl-1"> </span><span class="hl-3">"password"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isInvalid</span><span class="hl-2">:</span><span class="hl-1"> ({ </span><span class="hl-2">password</span><span class="hl-1">, </span><span class="hl-2">confirmPassword</span><span class="hl-1"> }) </span><span class="hl-4">=></span><br/><span class="hl-1"> </span><span class="hl-2">password</span><span class="hl-1"> === </span><span class="hl-2">confirmPassword</span><span class="hl-1"> ? </span><span class="hl-4">null</span><span class="hl-1"> : </span><span class="hl-3">"Passwords do not match"</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">type:</span><span class="hl-1"> </span><span class="hl-2">FieldType</span><span class="hl-1">.</span><span class="hl-2">CheckBox</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">name:</span><span class="hl-1"> </span><span class="hl-3">"termsAccepted"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-2">title:</span><span class="hl-1"> </span><span class="hl-3">"I accept the terms and conditions"</span><span class="hl-1">,</span><br/><span class="hl-1"> </span><span class="hl-5">isInvalid</span><span class="hl-2">:</span><span class="hl-1"> ({ </span><span class="hl-2">termsAccepted</span><span class="hl-1"> }) </span><span class="hl-4">=></span><br/><span class="hl-1"> </span><span class="hl-2">termsAccepted</span><span class="hl-1"> ? </span><span class="hl-4">null</span><span class="hl-1"> : </span><span class="hl-3">"You must accept the terms"</span><span class="hl-1">,</span><br/><span class="hl-1"> },</span><br/><span class="hl-1"> ],</span><br/><span class="hl-1"> },</span><br/><span class="hl-1">];</span> |
| </code><button type="button">Copy</button></pre> |
|
|
| <blockquote> |
| <p><strong>Note:</strong> The AI does not need to write any <code>useState</code>, <code>useEffect</code>, or form submission logic. <code><One /></code> manages state automatically. You only add an <code>onChange</code> handler to collect the final data object.</p> |
| </blockquote> |
| <a id="tips-for-better-ai-output" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Tips for better AI output<a href="#tips-for-better-ai-output" 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>Include the import line in your sample</strong></p> |
| <p>LLMs use the import statement to confirm the library name and available exports. Always include <code>import { TypedField, FieldType } from "react-declarative"</code> in the sample you provide.</p> |
| <p><strong>Ask for validation in isInvalid, not external logic</strong></p> |
| <p>Prompt the AI to put validation inside <code>isInvalid</code> callbacks rather than in a separate validation function. The callback approach keeps the schema self-contained and runnable in the playground.</p> |
| <p><strong>Specify responsive breakpoints explicitly</strong></p> |
| <p>Ask for <code>desktopColumns</code>, <code>tabletColumns</code>, and <code>phoneColumns</code> on each field if you need multi-column layouts. Otherwise the AI may default to full-width on all breakpoints.</p> |
| <p><strong>Use the gallery_of_controls sample for unfamiliar field types</strong></p> |
| <p>If you need a field type you haven't used before (e.g., <code>FieldType.Tree</code> or <code>FieldType.Dict</code>), include the gallery sample in your prompt so the AI has a concrete example to follow.</p> |
| <p><strong>Iterate in the playground, not in your editor</strong></p> |
| <p>Paste each AI output into <a href="https://react-declarative-playground.github.io/">react-declarative-playground.github.io</a> before copying it to your codebase. The playground catches schema errors instantly without requiring a build step.</p> |
| <a id="setting-up-a-local-ai-knowledge-base" class="tsd-anchor"></a><h2 class="tsd-anchor-link">Setting up a local AI knowledge base<a href="#setting-up-a-local-ai-knowledge-base" 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>For teams, you can build an offline Q&A knowledge base from the <code>react-declarative</code> documentation using <a href="https://www.nomic.ai/gpt4all">GPT4All</a> and its LocalDocs feature. Clone the repository, point LocalDocs at the <code>docs/</code> folder, and the model can answer questions grounded in the actual source documentation.</p> |
| <pre><code class="bash"><span class="hl-5">git</span><span class="hl-1"> </span><span class="hl-3">clone</span><span class="hl-1"> </span><span class="hl-3">https://github.com/react-declarative/react-declarative.git</span> |
| </code><button type="button">Copy</button></pre> |
|
|
| <p>Then open GPT4All, create a new LocalDocs collection pointing at the cloned <code>docs/</code> folder, and attach it to any chat session. This is useful for onboarding and for answering questions about less common API surface area that public LLMs may not have seen in training.</p> |
| </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="#generating-ui-with-ai-using-json-schemas"><span>Generating UI with AI using JSON schemas</span></a><ul><li><a href="#try-it-in-the-playground-first"><span>Try it in the playground first</span></a></li><li><a href="#why-llms-work-well-with-this-format"><span>Why LLMs work well with this format</span></a></li><li><a href="#the-prompt-workflow"><span>The prompt workflow</span></a></li><li><a href="#reference-samples"><span>Reference samples</span></a></li><li><ul><li><a href="#order_info--multi-section-form-with-date-and-combo-fields"><span>order_<wbr/>info β multi-<wbr/>section form with date and combo fields</span></a></li><li><a href="#login_form--centered-card-with-action-feedback"><span>login_<wbr/>form β centered card with action feedback</span></a></li><li><a href="#profile_card--avatar-layout-with-nested-groups"><span>profile_<wbr/>card β avatar layout with nested groups</span></a></li><li><a href="#settings_page--grouped-settings-with-switches-and-sliders"><span>settings_<wbr/>page β grouped settings with switches and sliders</span></a></li><li><a href="#gallery_of_controls--one-of-every-field-type"><span>gallery_<wbr/>of_<wbr/>controls β one of every field type</span></a></li><li><a href="#typography--display-only-content-layouts"><span>typography β display-<wbr/>only content layouts</span></a></li><li><a href="#product_shape--e-commerce-product-form"><span>product_<wbr/>shape β e-<wbr/>commerce product form</span></a></li><li><a href="#variant_form--conditional-field-visibility"><span>variant_<wbr/>form β conditional field visibility</span></a></li><li><a href="#adaptive_form--responsive-multi-column-layout"><span>adaptive_<wbr/>form β responsive multi-<wbr/>column layout</span></a></li><li><a href="#dashboard--kpi-cards-and-data-display"><span>dashboard β KPI cards and data display</span></a></li><li><a href="#account_info--account-management-form"><span>account_<wbr/>info β account management form</span></a></li><li><a href="#custom_jsx--arbitrary-jsx-inside-a-form"><span>custom_<wbr/>jsx β arbitrary JSX inside a form</span></a></li></ul></li><li><a href="#example-generating-a-registration-form"><span>Example: generating a registration form</span></a></li><li><a href="#tips-for-better-ai-output"><span>Tips for better AI output</span></a></li><li><a href="#setting-up-a-local-ai-knowledge-base"><span>Setting up a local AI knowledge base</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> |
|
|