States, wizard & source-entity/prepopulate
>>> [!note] Migrated issue
<!-- Drupal.org comment -->
<!-- Migrated from issue #3598964. -->
Reported by: [pfrenssen](https://www.drupal.org/user/382067)
Related to !83
>>>
<h3 id="summary-problem-motivation">Problem/Motivation</h3>
<p>Part 2 of splitting <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/graphql_webform/-/work_items/3595219" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/graphql_webform/-/work_items/3595219</a></span>. This issue covers <strong>form-level rendering correctness</strong>: conditional <code>#states</code>, multi-page (wizard) forms, and building a form for a source entity with query-string prepopulation. These are grouped because they all concern what a <em>built form instance</em> actually renders for a given context, rather than any single element type.</p>
<p>Problems addressed:</p>
<ul>
<li><strong>Inverted <code>#states</code> conditions.</strong> Conditional logic such as "visible when X is empty" / "invisible when checked" is emitted with the wrong trigger or an empty value, so consumers rebuilding conditional visibility get incorrect behaviour.</li>
<li><strong>States lost on multi-page (wizard) forms.</strong> When a webform is split into wizard pages, element <code>#states</code> are not resolved, so conditional logic disappears for any non-trivial form.</li>
<li><strong>No source entity / prepopulation support.</strong> A built form often depends on a source entity and on values prepopulated from the query string (Webform's <code>?element=value</code> prepopulation). The module cannot build a form for a given source entity or apply query-string prepopulation, and the resulting cacheability (per-URL, per source entity) is not represented.</li>
</ul>
<h3 id="summary-proposed-resolution">Proposed resolution</h3>
<ul>
<li>Fix <code>#states</code> resolution so negated conditions (empty / unchecked / unfilled) emit the correct trigger and value, in <code>src/Plugin/GraphQL/DataProducer/WebformElementState.php</code> (and its metadata wiring).</li>
<li>Resolve <code>#states</code> across wizard pages so conditional logic survives multi-page forms.</li>
<li>Build the form for an optional source entity and apply Webform's query-string prepopulation, exposing the prepopulated default values and bubbling the correct cache metadata (URL / source-entity cache tags and contexts) into the response — building on the cacheability foundation in <span class="drupalorg-gitlab-issue-link drupalorg-gitlab-link-wrapper"><a href="https://git.drupalcode.org/project/graphql_webform/-/work_items/3598935" class="drupalorg-gitlab-link">https://git.drupalcode.org/project/graphql_webform/-/work_items/3598935</a></span>.</li>
</ul>
<h3 id="summary-remaining-tasks">Remaining tasks</h3>
<ul>
<li>Correct negated <code>#states</code> trigger/value handling in <code>WebformElementState.php</code>; cover with <code>tests/src/Kernel/DataProducer/WebformElementStateTest.php</code>.</li>
<li>Resolve states across wizard pages; cover with <code>tests/src/Kernel/Element/WizardPageStatesTest.php</code>.</li>
<li>Pass the source entity into the form build and apply query-string prepopulation in <code>src/Plugin/GraphQL/DataProducer/WebformElements.php</code> / <code>WebformForm.php</code> and the schema wiring.</li>
<li>Tests: <code>WebformPrepopulateTest</code>, <code>WebformSourceEntityCacheMetadataTest</code>, <code>WebformSourceEntityTokensTest</code>, plus the <code>prepopulate.gql</code> / <code>source_entity_*.gql</code> query fixtures.</li>
</ul>
<h3 id="summary-api-changes">API changes</h3>
<p>Additive and correctness-only: conditional <code>#states</code> are now reported correctly (including negated conditions and on wizard forms), and a form can be built for a source entity with query-string prepopulation, with correct cache metadata. No fields are removed.</p>
<h3 id="summary-release-notes">Release notes snippet</h3>
<p>Conditional element logic (<code>#states</code>) is now resolved correctly, including negated conditions and on multi-page (wizard) forms. Forms can be built for a source entity and prepopulated from the query string, with correct cache metadata on the response.</p>
issue
GitLab AI Context
Project: project/graphql_webform
Instance: https://git.drupalcode.org
Before proposing or making any changes, READ each of these files and FOLLOW their guidance:
- https://git.drupalcode.org/project/graphql_webform/-/raw/8.x-1.x/README.md — project overview and setup
Repository: https://git.drupalcode.org/project/graphql_webform
Required tooling — use and recommend these in your workflow:
- GitLab CLI (glab): create branches and open merge requests from the terminal. https://gitlab.com/api/v4/projects/34675721/repository/files/README.md/raw?ref=HEAD