Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions articles/building-apps/ai/quickstart-guide.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ page-title: Quick Start-Guide | AI Chatbot with Vaadin
description: A compact chat view with streaming, correct scrolling, and message context.
meta-description: Hands-on tutorial - connect Vaadin to an LLM with Spring, build a streaming chat UI, and apply simple, reusable patterns for prompts, memory, and UX.
order: 20
section-nav: badge-preview badge-flow
section-nav: badge-preview
---
= [since:com.vaadin:vaadin@V25.1]#Quick Start-Guide: Add an AI Chat Bot to a Vaadin + Spring Boot Application# [badge-flow]#Flow#
= [since:com.vaadin:vaadin@V25.1]#Quick Start-Guide: Add an AI Chat Bot to a Vaadin + Spring Boot Application#

:preview-feature: AI integration features
:feature-flag: com.vaadin.experimental.aiComponents
Expand Down
2 changes: 1 addition & 1 deletion articles/building-apps/ai/technical-setup/ide/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,4 @@ If you're unsure how to set environment variables in your specific IDE, see:
Run the application and check that the model call succeeds. If you see authentication errors, confirm the variable is set in the environment that starts the JVM and that your configuration references `${OPENAI_API_KEY}`.

[NOTE]
For Java/IDE requirements and plugins, see <</getting-started/dev-environment#,Development Environment Instructions>>.
For Java/IDE requirements and plugins, see <</getting-started/dev-environment#,Development Environment>>.
10 changes: 5 additions & 5 deletions articles/building-apps/architecture/layers.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ In traditional web applications, you have the _frontend_ and the _backend_. The

[.fill]
[link=images/layers.png]
image::images/layers.png[A diagram illustrating the UI layer and application layer of a Flow and a Hilla app, respectively]
image::images/layers.png[A diagram illustrating the UI layer and application layer of a Flow view and a React view, respectively]

When you are building your user interface with Flow, you write the user interface in Java and run it on the server - the backend. Unless you have created any web components of your own, all the code that runs in the browser -- the frontend -- is provided by Vaadin in one way or the other. The frontend and backend don't map directly onto the user interface and business logic.
When you are building your user interface with Flow views, you write the user interface in Java and run it on the server -- the backend. Unless you have created any web components of your own, all the code that runs in the browser -- the frontend -- is provided by Vaadin in one way or the other. The frontend and backend don't map directly onto the user interface and business logic.

When you are building your user interface with Hilla, you write the user interface in React and run it in the browser. The rest of the application runs on the server. In this case, the frontend and backend correspond to the user interface and business logic.
When you are building your user interface with React views, you write the user interface in React and TypeScript, and run it in the browser. The rest of the application runs on the server. In this case, the frontend and backend correspond to the user interface and business logic.

It's also possible to write hybrid applications, where you write some parts of the user interface in Java and other parts in React. In this case, parts of the user interface run in the browser and parts on the server.
An application can also combine the two, with some views written as Flow views and others as React views. In this case, parts of the user interface run in the browser and parts on the server.

Because of this, it makes more sense to talk about the UI layer and the application layer, as opposed to the frontend and the backend, or the user interface and the business logic. It's important to remember that these layers are _conceptual_ rather than physical. In a Flow or hybrid application, the UI layer covers both the browser and a part of the server. In a Hilla application, the UI layer is limited to the browser alone. In all cases, the application layer resides on the server.
Because of this, it makes more sense to talk about the UI layer and the application layer, as opposed to the frontend and the backend, or the user interface and the business logic. It's important to remember that these layers are _conceptual_ rather than physical. For Flow views, the UI layer covers both the browser and a part of the server. For React views, the UI layer is limited to the browser alone. In all cases, the application layer resides on the server.

In practice, the UI layer consists of your <<../views#,Flow views>> and, if you have any, your <<../react#,React views>>. The application layer consists of the <<../business-logic/add-service#,application services>> that the views call, and everything behind them.
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ page-title: How to use callbacks to interact with your UI | Vaadin
description: How to use callbacks to interact with the user interface.
meta-description: When using a Flow user interface, the simplest way of allowing background jobs to interact with it is through callbacks. Learn more here.
order: 10
section-nav: badge-flow
---


= Callbacks [badge-flow]#Flow#
= Callbacks

When using a Flow user interface, the simplest way of allowing background jobs to interact with it is through callbacks. You can use `Consumer`, `Runnable`, and `Supplier` as callback interfaces, depending on how you want to interact with the background job.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ page-title: How to use CompletableFuture to interact with your app's UI
description: How to use CompletableFuture to interact with the user interface.
meta-description: Learn to use standard Java `CompletableFuture` with your user interface in your application.
order: 20
section-nav: badge-flow
---


= Returning Futures [badge-flow]#Flow#
= Returning Futures

When using a Flow user interface, you can use a standard Java `CompletableFuture` to report results and errors to it, and to cancel the job. For reporting progress, however, you still need to use a callback.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ If the job can't report its progress, call `progressBar.setIndeterminate(true)`

== Options

The example above is one way of letting the user interface and a background job interact. The following pages cover the different options in more detail:
The example above is one way of letting the user interface and a background job interact. Callbacks and futures work only with Flow views, whereas reactive streams also work with <</building-apps/react#,React views>>. The following pages cover the different options in more detail:

section_outline::[]
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ order: 30

= Producing Reactive Streams

When using Flow or Hilla to build your user interface, you can use `Flux` or `Mono` from https://projectreactor.io/[Reactor] to allow your background jobs to interact with them. Reactor has an extensive API, which means you can do many things with it. This also means that it can be more difficult to learn than using callbacks or `CompletableFuture`.
You can use `Flux` or `Mono` from https://projectreactor.io/[Reactor] to allow your background jobs to interact with the user interface. Unlike <<callbacks#,callbacks>> and <<futures#,futures>>, reactive streams work with both Flow views and <</building-apps/react#,React views>>. Reactor has an extensive API, which means you can do many things with it. This also means that it can be more difficult to learn than using callbacks or `CompletableFuture`.

This page is about returning the result of a background job to the user who started it. You can also use reactive streams to broadcast updates to all users. That use case is covered in <</building-apps/server-push/reactive#,Consuming Reactive Streams>> and <</building-apps/server-push/updates#broadcasting-to-all-users,Broadcasting to All Users>>.

Expand All @@ -32,21 +32,21 @@ public Mono<String> startBackgroundJob() {

If the `doSomethingThatTakesALongTime()` method throws an exception, the `Mono` terminates with an error.

To update the user interface, you have to subscribe to the `Mono` or `Flux`. For more information about how to do this, see the <</building-apps/server-push/reactive#,Consuming Reactive Streams>> documentation page.
To update the user interface, you have to subscribe to the `Mono` or `Flux`. For more information about how to do this in a Flow view, see the <</building-apps/server-push/reactive#,Consuming Reactive Streams>> documentation page. For React views, see <</hilla/guides/reactive-services#,Reactive Services>>.

[IMPORTANT]
Hilla only supports `Flux`, so if your job is returning a `Mono`, you have to convert it to a `Flux` inside your `@BrowserCallable` service. You can do this by calling the `Mono.flux()` method.
A React view calls the job through a <</building-apps/react/call-services#,browser-callable service>>, which can return a `Flux` but not a `Mono`. If your job returns a `Mono`, convert it to a `Flux` inside your `@BrowserCallable` service by calling the `Mono.flux()` method.


== Reporting Progress

If your background job only needs to report its progress without actually returning a result, you can return a `Flux<Double>`. Your job should then emit progress updates, and complete the stream when done. However, you may often want also to return a result. Since Hilla only supports returning a single `Flux`, you have to use the same stream for emitting both progress updates and the end result. The code may be a bit messy, but it works.
If your background job only needs to report its progress without actually returning a result, you can return a `Flux<Double>`. Your job should then emit progress updates, and complete the stream when done. However, you may often want also to return a result. The simplest way to do this, which also works for React views, is to use the same stream for emitting both progress updates and the end result. The code may be a bit messy, but it works.

You first need to create a data type that can contain both progress updates and the result. For a job that returns a string, it could look like this:

[source,java]
----
import com.vaadin.hilla.Nullable;
import org.jspecify.annotations.Nullable;

public record BackgroundJobOutput(
@Nullable Double progressUpdate,
Expand All @@ -64,9 +64,6 @@ public record BackgroundJobOutput(

The two built-in methods, `progressUpdate()` and `finished()` make the code look better when it's time to create instances of `BackgroundJobOutput`.

[NOTE]
If you've worked with sealed classes, you may be tempted to create a sealed interface called `BackgroundJobOutput`, and then create two records that implement that interface: one for progress updates; and another for the result. However, Hilla doesn't support this at the moment.

Next, you have to implement the background job like this:

[source,java]
Expand Down
10 changes: 6 additions & 4 deletions articles/building-apps/components/build-component.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Pair it with CSS in your stylesheet:
----
.status-badge {
align-items: center;
gap: var(--lumo-space-xs);
gap: var(--vaadin-gap-xs);
}

.status-badge-indicator {
Expand All @@ -64,11 +64,13 @@ Pair it with CSS in your stylesheet:
border-radius: 50%;
}

.status-success { background: var(--lumo-success-color); }
.status-warning { background: var(--lumo-warning-color); }
.status-error { background: var(--lumo-error-color); }
.status-success { background: var(--aura-green); }
.status-warning { background: var(--aura-yellow); }
.status-error { background: var(--aura-red); }
----

The status colors come from Aura, the default theme. With Lumo, use `--lumo-success-color`, `--lumo-warning-color`, and `--lumo-error-color` instead. See <<style-component#use-theme-custom-properties,Use Theme Custom Properties>> for more about choosing properties.


== When to Create a Component

Expand Down
34 changes: 25 additions & 9 deletions articles/building-apps/components/style-component.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ order: 20
= Style a Component
:toclevels: 2

This article shows how to add styling to custom components you've built. The focus is on creating maintainable, theme-consistent styles that work in both light and dark mode. For general styling guidance, see <<../ui-basics/add-styling#,Add Styling>>. For the full styling reference, see the <</styling#,Styling>> documentation.
This article shows how to add styling to custom components you've built. The focus is on creating maintainable, theme-consistent styles that work in both light and dark mode. For general styling guidance, see <<../ui-basics/add-styling#,Add Styling>>. For the full styling reference, see the <<{articles}/styling#,Styling>> documentation.


== Copy-Paste Example
Expand Down Expand Up @@ -152,9 +152,27 @@ Vaadin provides three levels of custom properties:
| `var(--vaadin-radius-m)`
|===

See <</styling/themes/base#,Base Styles>> for the full list.
See <<{articles}/styling/themes/base#,Base Styles>> for the full list.

*Lumo properties* (`--lumo-*`) offer a richer set of properties for applications using the <<{articles}/styling/themes/lumo#,Lumo>> theme:
*Aura properties* (`--aura-*`) are for applications using the <<{articles}/styling/themes/aura#,Aura>> theme, which is the default theme. Aura defines its own color system and maps it to the base properties:

[cols="1,1",options="header"]
|===
| Instead of | Use

| `#1676f3`
| `var(--aura-accent-color)`

| `14px`
| `var(--aura-font-size-s)`

| `#d32f2f`
| `var(--aura-red)`
|===

See <<{articles}/styling/themes/aura/color#,Aura Color>> and <<{articles}/styling/themes/aura/typography#,Aura Typography>> for the full list.

*Lumo properties* (`--lumo-*`) are for applications using the <<{articles}/styling/themes/lumo#,Lumo>> theme:

[cols="1,1",options="header"]
|===
Expand All @@ -166,13 +184,11 @@ See <</styling/themes/base#,Base Styles>> for the full list.
| `14px`
| `var(--lumo-font-size-s)`

| `#333`
| `var(--lumo-body-text-color)`
| `#d32f2f`
| `var(--lumo-error-color)`
|===

See <</styling/themes/lumo/lumo-style-properties#,Lumo Style Properties>> for the full list.

*Aura properties* (`--aura-*`) are for applications using the <<{articles}/styling/themes/aura#,Aura>> theme, which defines its own color system and maps it to the base properties.
See <<{articles}/styling/themes/lumo/lumo-style-properties#,Lumo Style Properties>> for the full list.

[TIP]
.Choosing the Right Properties
Expand Down Expand Up @@ -248,7 +264,7 @@ Prefix custom property names with the component name to avoid clashes.

== Pitfalls

*Use theme properties, not hardcoded values.* Hardcoded colors, sizes, and fonts break theme consistency and don't adapt to dark mode. Use `--vaadin-*` base properties for theme-agnostic components, or `--lumo-*` / `--aura-*` properties if you target a specific theme.
*Use theme properties, not hardcoded values.* Hardcoded colors, sizes, and fonts break theme consistency and don't adapt to dark mode. Use `--vaadin-*` base properties for theme-agnostic components, or `--aura-*` / `--lumo-*` properties if you target a specific theme.

*Use semantic class names.* Name classes after what the element represents, not its appearance. `notification-banner` is better than `yellow-box` — the color might change, but the purpose won't.

Expand Down
2 changes: 2 additions & 0 deletions articles/building-apps/forms-data/add-form/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ In business applications, forms play a central role in *displaying and collectin

Vaadin offers a range of components and utilities to simplify form building. However, because forms and data binding cover a broad area, the topic is divided into several focused guides. Each one covers a specific aspect of form development.

The guides use Flow views. For forms in React views, see the <</hilla/guides/forms#,Forms>> reference guide.

section_outline::[]
13 changes: 12 additions & 1 deletion articles/building-apps/forms-data/add-form/validation.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -275,9 +275,20 @@ For `Binder`-level validation errors, which do not belong to a specific field, y
[source,java]
----
var beanValidationErrors = new Div();
beanValidationErrors.addClassName(LumoUtility.TextColor.ERROR);
beanValidationErrors.addClassName("form-errors");

binder.setStatusLabel(beanValidationErrors);
----

Then give the status label an error color in your stylesheet:

[source,css]
----
.form-errors {
color: var(--aura-red-text);
}
----

The color comes from Aura, the default theme. With Lumo, use `var(--lumo-error-text-color)` instead.

This ensures that validation messages are displayed appropriately, whenever they originate from `Binding`-level validation or `Binder`-level validation.
2 changes: 2 additions & 0 deletions articles/building-apps/forms-data/add-grid/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,5 @@ You can use the Grid component with all these data types, but the implementation
section_outline::[]

For detailed information about binding data sets to UI components in Vaadin, see the <</flow/binding-data/data-provider#,Data Provider>> reference guide.

The guides use Flow views. For grids in React views, see the <</hilla/guides/data-grids#,Data Grids>> reference guide.
Loading
Loading