Skip to content

docs: move full-stack signals to UI State - #6624

Merged
peholmst merged 3 commits into
mainfrom
claude/full-stack-signals
Nov 11, 2026
Merged

peholmst merged 3 commits into
mainfrom
claude/full-stack-signals

Conversation

@peholmst

Copy link
Copy Markdown
Member

Review risk: two-way door. Docs and examples only: one new reference page, one removed page with a redirect, a new section on Shared Signals, and link updates. Reverting brings the old page back.

Summary

Moves full-stack signals from the Hilla guides to the Flow UI State section, as the new page Shared Signals in React Views (flow/ui-state/full-stack-signals). This is the seventh step of dissolving the Hilla section, after #6611, #6616, #6618, #6620, #6621 and #6622.

The page is a reference: which shared signal types a service can return, the client API of the signals, how they connect and synchronize, and how the access annotations apply. It's rewritten for 25.4, because most of the old page described an API that no longer exists. Every statement is checked against main of vaadin/hilla and vaadin/flow, and the behavior is checked in a scratch 25.4.0-alpha5 application with two browser tabs. This pull request targets main only, so it gets no target/v25.3 label.

What changed

  • New page flow/ui-state/full-stack-signals.adoc, marked as a preview feature behind the fullstackSignals feature flag:
    • the supported types (SharedValueSignal, SharedNumberSignal, SharedListSignal) and their TypeScript counterparts;
    • returning one instance from the service, and service methods with parameters;
    • creating, connecting and reading the signals in a view, and default values;
    • the members of ValueSignal, NumberSignal and ListSignal, and operation results;
    • changes made on the server;
    • access control.
  • Shared Signals: a new Validating Changes section for withValidator() and CommandValidator, which the Flow page didn't cover. The UI State index links to the new page.
  • Feature Flags: fullstackSignals moves to the list of experimental flags, and the Hilla Feature Flags heading goes away.
  • Examples: a compiled MeetingService and a view that uses a value, number and list signal, replacing the inline examples.
  • Removed page, with a redirect: hilla/guides/full-stack-signals → flow/ui-state/full-stack-signals.
  • Links: Type Conversion now links to the new page.
  • Corrections compared with the old page, each checked in the scratch application:
    • ValueSignal has no replace() or update() anymore (feat!: integrate Vaadin signals library in Hilla (ValueSignal) hilla#3500), and ListSignal has insertFirst() as well.
    • The operation-validator API (withOperationValidator, ValidationResult, IncrementOperation, …) no longer exists. Flow's shared signals use withValidator(CommandValidator), which is now on the Shared Signals page.
    • new SharedValueSignal<>(false, Boolean.class) doesn't compile. The constructors take an initial value, a type, or both as a TypeReference.
    • The list example used the index as the React key. Each item signal has a stable id.
    • SharedMapSignal and SharedNodeSignal aren't supported. The generator produces a plain method for them.

Test summary

  • npm run check-redirects passes.
  • mvn spotless:apply and mvn compile pass. npx eslint frontend/demo/fusion/signals passes.
  • The example service and view type-check in the scratch 25.4.0-alpha5 application. Two tabs share the topic, the votes, and the agenda items: adding, checking and removing items all sync.
  • Checked with the browser and the generated client:
  • withValidator(), chained validators, child signals, transactions and asReadonly() checked with a small program against the 25.4.0-alpha5 classpath.
  • Every cross reference in the new and changed lines resolves.
  • Vale: no errors or warnings on the added and changed lines with the pull request configuration.
  • Asciidoctor renders the new and changed pages, with all includes and tags resolved.
  • I didn't run a full dspublisher build locally.

Behaviors that came up during testing, which the page describes as they are:

🤖 Generated with Claude Code

Replace the Hilla Full-Stack Signals guide with the reference page
Shared Signals in React Views under flow/ui-state, rewritten for 25.4
and marked as a preview feature behind the fullstackSignals flag. The
examples are now a compiled service and view.

Add a section on withValidator() and CommandValidator to Shared
Signals, move fullstackSignals to the experimental feature flags, and
redirect the old page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@vaadin-review-bot vaadin-review-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changes — left 3 comments.

Finding
⚠️ The default-value statement and the examples only hold when the service package is @NullMarked, and the page never says so.
💬 Access Control doesn't say that validators on the returned signal don't apply to changes from the browser.
⚠️ When a change to a list item fails, the error goes to the list signal, not to the item signal the page tells readers to change.

peholmst and others added 2 commits November 11, 2026 12:39
The docs build aliases @vaadin/hilla-react-signals to
@preact/signals-react, so the generated client of a service that
returns a shared signal can't import ListSignal, NumberSignal and
ValueSignal. Alias it to a module that re-exports @preact/signals-react
and adds placeholders for those classes, which the live examples never
create.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The default value and the generated types depend on nullability, and a
failed change to a list item sets the error of the list signal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vaadin vaadin deleted a comment from vaadin-review-bot Nov 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment

This PR has been deployed for preview.

URL: https://docs-preview-pr-6624.fly.dev

Changed pages

Added content is highlighted in green; removed content is marked in red on each page.

Other changed files

  • articles/hilla/guides/full-stack-signals.adoc (deleted)
  • frontend/demo/services/react-signals.ts (added)
  • src/main/java/com/vaadin/demo/fusion/signals/package-info.java (added)

Built from 1bf1c70

@peholmst
peholmst merged commit dc19042 into main Nov 11, 2026
11 checks passed
@peholmst
peholmst deleted the claude/full-stack-signals branch November 11, 2026 11:54
peholmst added a commit that referenced this pull request Nov 11, 2026
**Review risk:** two-way door. Docs and examples only: one new page, two
rewritten or extended pages, five removed pages with redirects, and link
and guideline updates. Reverting brings the old pages back.

## Summary
Moves React i18n, the connection indicator and React styling from the
Hilla section to the Flow Reference and the Styling section. This is the
eighth step of dissolving the Hilla section, after #6611, #6616, #6618,
#6620, #6621, #6622 and #6624.

Every statement is checked against `main` of vaadin/hilla and
vaadin/flow, and the behavior is checked in a scratch application on
25.4.0-alpha5 with Flow 25.4.0-alpha6, the first Flow release with
vaadin/flow#26714. This pull request targets `main` only, so it gets no
`target/v25.3` label.

## What changed
- **New page** `flow/i18n/react-views.adoc`, Localization in React
Views, rewritten from the Hilla i18n guide with compiled examples:
- loading translations with `i18n.configure()`, and how the initial
language is chosen;
- `translate()` and the `key` tag, the missing-translation marker, and
ICU parameters compared with Flow's `MessageFormat`;
- translating view titles and menu items with `translateDynamic()`,
including the `@Menu` titles of Flow views;
- changing the language, the file fallback, and that the React language
is separate from the Flow `UI` locale;
- development and production loading, and what a custom `I18NProvider`
must implement.
- **Loading and Connection Indicator**
(`flow/advanced/loading-indicator.adoc`) now also covers what the Hilla
connection indicator page covered:
- it covers Flow and React views, the loading bar stages, and the
connection status messages;
- configuration from Java, including `ReconnectDialogConfiguration`,
which no page documented, with a compiled example;
- configuration from TypeScript, with the `jar-resources` import that
replaces `@vaadin/common-frontend` after vaadin/flow#26714;
  - styling, with the element structure and states.
- **Stylesheets:** a new Stylesheets in React Views section: global
`@StyleSheet` styles, importing CSS files and CSS modules from a view,
and the type declarations these imports need.
- **Localization and Custom I18N Provider** link to the new page.
- **Removed pages, with redirects:**
  - `hilla/guides/i18n` → `flow/i18n/react-views`
- `hilla/reference/connection-indicator` →
`flow/advanced/loading-indicator` (the Lit redirect points there too)
  - `hilla/guides/styling` → `styling/stylesheets#react-views`
- `hilla/reference`, now empty → `flow/react-views` (the Lit redirect
points there too). This was planned for the last step.
  - The last partial in `articles/hilla/_shared` is removed.
- **Links:** the Routing page links to the new i18n page.
- **Guidelines:** the Hilla paragraph no longer mentions the `_shared`
partials, and the feature flag guideline no longer names the Hilla
Feature Flags section that #6624 removed.
- **Corrections** compared with the old pages, each checked in the
scratch application:
  - A missing translation shows as `!de: key`, not as the key.
- The old guide wrapped `i18n.configure()` in an effect. It returns a
`Promise`, and the page awaits it once in the layout.
  - The default first delay of the loading bar is 450 ms, not 300 ms.
- The old CSS examples didn't show anything with the default theme
turned off: the indicator's functional style, which is always present,
comes after the application's stylesheets and sets `opacity: 0` and
`pointer-events: none`. The examples now use
`vaadin-connection-indicator .v-loading-indicator` and set `opacity`.
- The `@vaadin/common-frontend` import no longer works after
vaadin/flow#26714.

## Test summary
- `npm run check-redirects` passes.
- `mvn spotless:apply` and `mvn compile` pass. `npx eslint
frontend/demo/fusion/i18n` passes.
- The two TypeScript examples type-check and run in the scratch
application, in English and German.
- Checked with the browser:
- translations, the ICU plural form, `{0}` placeholders, the missing-key
marker, on-demand keys and their warning;
- the cookie, the fallback from `de-DE` to `de` and the root file, and
the separate Flow locale;
- a custom provider without `getAllTranslations()` in development mode
(no translations; `initialized` stays `false`);
- the loading bar stages during a slow service call, the offline message
after a failed call and after the browser's `offline` event, and the
online message afterwards;
  - the reconnecting message of a Flow view with the server stopped;
- the TypeScript configuration, the Java configuration overriding only
the properties it sets, and the corrected curtain CSS;
- global styles, a plain CSS import that stays loaded after navigating
away, and a CSS module.
- Every cross reference in the new and changed lines resolves.
- Vale: no errors or warnings on the added and changed lines with the
pull request configuration.
- Asciidoctor renders the changed pages, with all includes and tags
resolved.
- I didn't run a full dspublisher build locally.

The TypeScript configuration snippet for the indicator is inline: the
docs build is on 25.4.0-alpha5, whose `Flow.js` still uses
`@vaadin/common-frontend`, so a compiled example importing the new
module wouldn't build yet.

Product bugs found during testing, reported separately:
- vaadin/flow#26970: `types.d.ts` doesn't declare CSS imports, so with
TypeScript 6 the imports in React views fail the type check. The
Stylesheets section documents the declarations to add.
- vaadin/hilla#7050: after `setLanguage()`, a key that
`translateDynamic()` loaded on demand stays empty. The page doesn't
describe this behavior.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants