Skip to content

Commit

Permalink
Merge branch 'latest' into feat/focusable-disabled-buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
russelljtdyer authored Jan 26, 2025
2 parents 19800fa + 238ec66 commit fad3958
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 23 deletions.
6 changes: 3 additions & 3 deletions articles/components/app-layout/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ With Flow, the root layout can be defined using the <<{articles}/flow/routing/la
[source,java]
----
@Layout
public class MainLayout extends AppLayout implements RouterLayout {
public class MainLayout extends AppLayout {
}
----
Expand Down Expand Up @@ -138,7 +138,7 @@ The `navbar` is a header above the content area. It can contain primary or secon
----
<source-info group="Flow"></source-info>
@Layout
public class MainLayout extends AppLayout implements RouterLayout {
public class MainLayout extends AppLayout {
public MainLayout() {
H1 title = new H1("My App");
addToNavbar(title);
Expand Down Expand Up @@ -233,7 +233,7 @@ The `drawer` can switch between a fixed area next to the view's content and an e
----
<source-info group="Flow"></source-info>
@Layout
public class MainLayout extends AppLayout implements RouterLayout {
public class MainLayout extends AppLayout {
public MainLayout() {
SideNav nav = new SideNav();
addToDrawer(nav);
Expand Down
2 changes: 1 addition & 1 deletion articles/components/date-picker/date-formats.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ Other characters, such as separators (e.g., `/`, `.`, `-`) or spaces may be used
Custom date patterns take precedence over the configured locale. When using both at the same time, the custom date pattern is used to display and parse dates.
endif::[]


[role="since:com.vaadin:[email protected]"]
== Server-Side Parsing in Flow

The Flow version of Date Picker also allows you to provide a server-side parser that may be used as a fallback when user input can't be parsed using the methods described previously. The parser is a function that receives the user entered string and returns either a parsed date or an error message. Successfully parsed dates are displayed in the field using the same pattern as other dates.
Expand Down
3 changes: 3 additions & 0 deletions articles/flow/configuration/maven.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ Build directory for the project. Defaults to `${project.build.directory}`.
`skipDevBundleRebuild`::
Prevents frontend development bundle from being re-built even if Vaadin decides to use an existing compiled development bundle. This is mainly needed when re-bundling checker in Flow has issues leading to false re-bundling and one needs a workaround while the problem is being resolved. Defaults to `false`.

`cleanFrontendFiles`::
Clears the generated frontend files after building a project for production. It keeps the generated files if they existed before the build, or if this parameter is set to `false`. When building a bundle in development mode, the generated files are removed unless they existed before the build. Defaults to `true`.

`frontendExtraFileExtensions`::
Parameter for adding file extensions to a handle when generating bundles.

Expand Down
5 changes: 5 additions & 0 deletions articles/flow/configuration/properties.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ The following table contains the properties that are used only by the Vaadin Mav
|`skipDevBundleRebuild`
|Prevents a frontend development bundle from being re-built, even if Vaadin Flow decides to use an existing compiled development bundle. This is mainly needed when re-bundling checker in Vaadin Flow has problems leading to false re-bundling, and one needs a workaround while it's being resolved.
|`false`

|`vaadin.clean.build.frontend.files`
|`cleanFrontendFiles`
|Clears the generated frontend files after building a project for production. It keeps the generated files if they existed before the build, or if this parameter is set to `false`. When building a bundle in development mode, the generated files are removed unless they existed before the build.
|`true`
|===

[discussion-id]`27BF72FB-1E23-42B0-B540-A602F9AD4571`
128 changes: 115 additions & 13 deletions articles/flow/routing/layout.adoc
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: Router Layouts pass:[&] Nested Router Targets
page-title: How to use layouts in Vaadin routing
page-title: Using Layouts in Vaadin Routing
description: Explains router layouts and nested router targets.
meta-description: Implement routing layouts in Vaadin to structure and organize your application user interface.
meta-description: Implement routing layouts in Vaadin to structure and organize an application user interface.
order: 40
---

Expand All @@ -11,25 +11,30 @@ order: 40

All parent layouts of a navigation target component have to implement the [interfacename]`RouterLayout` interface. You can define a parent layout by adding the [annotationname]`@Layout` annotation to the class, or by using the optional element `layout` from the `@Route` annotation.

[interfacename]`RouterLayout` interface appends and removes child route content during navigation. For more in depth information, see <<#Router Layout,Router Layout>>.


[role="since:com.vaadin:[email protected]"]
=== Automatic Layout Using `@Layout`

The value for the [annotationName]`@Layout` annotation path has to be unique for the project. Otherwise, the resolver won't be able to determine which layout component should be used. Having multiple [annotationName]`@Layout` annotations with the same path throws an exception.
The [annotationName]`@Layout` can be added to any [className]`Component` that implements [interfacename]`RouterLayout`.

The example below renders all routes inside [classname]`MainLayout`:

[source,java]
----
@Layout
public class MainLayout extends Div
implements RouterLayout {
public class MainLayout extends AppLayout {
}
----

If the application is using access protection, the view access is checked for the Layout, as well as the view. To make the layout accessible, add [annotationname]`@AnonymousAllowed` -- or some other access annotation -- on the `MainLayout` so that the request is not denied.
See <<{articles}/components/app-layout/#,`AppLayout`>> for more information on usage.

[annotationname]`@Route` and [annotationname]`@RouteAlias` each contain an annotation attribute called, `autoLayout`. Setting that attribute to false will stop automatic layout; it will ignore any [annotationname]`@Layout` matching the route. Giving a class for the `layout` method in [annotationname]`@Route` also disables automatic layout and uses the one given.
The value for the [annotationName]`@Layout` annotation path has to be unique for the project. Otherwise, the resolver won't be able to determine which layout component should be used. Having multiple [annotationName]`@Layout` annotations with the same path throws an exception.

If an application is using access protection, the view access is checked for the Layout, as well as the view. To make the layout accessible, add [annotationname]`@AnonymousAllowed` -- or some other access annotation -- on the `MainLayout` so that the request is not denied.

[annotationname]`@Route` and [annotationname]`@RouteAlias` each contain an annotation attribute called, `autoLayout`. Setting that attribute to false stops automatic layout; it ignores any [annotationname]`@Layout` matching the route. Giving a class for the `layout` method in [annotationname]`@Route` also disables automatic layout and causes the one given to be used.

.Ignore Automatic Layout
[source,java]
Expand Down Expand Up @@ -87,19 +92,18 @@ See <<page-titles#,Updating Page Title on Navigation>> for more information on t

Use the `@ParentLayout` annotation to define a parent layout for components in the routing hierarchy. Where necessary, a parent can have its own parent layout.

In the example below, `MainLayout` is used for everything, which `MenuBar` is reused for views:
In the example below, `MainLayout` is used for everything, and `SubMenu` is reused for views:

[source,java]
----
public class MainLayout extends Div
implements RouterLayout {
public class MainLayout extends AppLayout {
}
@Layout
@ParentLayout(MainLayout.class)
public class MenuBar extends Div
public class SubMenu extends Div
implements RouterLayout {
public MenuBar() {
public SubMenu() {
addMenuElement(TutorialView.class, "Tutorial");
addMenuElement(IconsView.class, "Icons");
}
Expand All @@ -119,7 +123,7 @@ public class IconsView extends Div {
}
----

`MainLayout` encapsulates `MenuBar`, which in turn encapsulates `TutorialView` or `IconsView` -- depending on where the user has navigated.
`MainLayout` encapsulates `SubMenu`, which in turn encapsulates `TutorialView` or `IconsView` -- depending on where the user has navigated.


== ParentLayout Route Control
Expand Down Expand Up @@ -181,4 +185,102 @@ The bound route is `framework/tutorial`, although the full chain is `some/framew

If a parent layout defines a `@RoutePrefix`, the "default" child could have its route defined as `@Route("")` and be mapped to the parent layout route. For example, `Tutorials` with route `""` would be mapped as `framework/`.


=== Router Layout

A class implementing the [interfacename]`RouterLayout` interface causes Vaadin to append and remove content on navigation to a route with the layout in the parent stack.

By default, the content is appended to the [interfacename]`RouterLayout` component. Anything added on navigation is positioned last.

.Layout Order Sample
[source,java]
----
public class ParentLayout extends Div implements RouterLayout {
public ParentLayout() {
add(new Span("Parent content"));
}
}
@Route(value = "route", layout = ParentLayout.class)
public class MyRoute extends Div {
public MyRoute() {
add(new Span("View content"));
}
}
----

.Sample Output
[source,text]
----
Parent content
View content
----

Adding elements after navigation in the parent puts the content after the view content.

.Layout Order Sample
[source,java]
----
public class ParentLayout extends Div implements RouterLayout {
public ParentLayout() {
add(new Span("Parent content"));
}
@Override
protected void onAttach(AttachEvent attachEvent) {
add(new Span("On attach"));
}
}
@Route(value = "route", layout = ParentLayout.class)
public class MyRoute extends Div {
public MyRoute() {
add(new Span("View content"));
}
}
----

.Sample Output
[source,text]
----
Parent content
View content
On attach
----

To customize content position, the method [methodname]`showRouterLayoutContent(HasElement content)` can be overridden. Even with [methodname]`showRouterLayoutContent` overridden, the content is removed from the component on navigation if not part of the new route.

.Custom Content Sample
[source,java]
----
public class ParentLayout extends Div implements RouterLayout {
private Div childHolder = new Div();
public ParentLayout() {
add(childHolder, new Span("Parent content"));
}
@Override
public void showRouterLayoutContent(HasElement content) {
if(content != null) {
childHolder.getElement().appendChild(content.getElement());
}
}
}
@Route(value = "route", layout = ParentLayout.class)
public class MyRoute extends Div {
public MyRoute() {
add(new Span("View content"));
}
}
----

.Sample Output
[source,text]
----
View content
Parent content
----

[discussion-id]`7A96749F-CD19-4422-A2A2-B4ACD719C9FA`
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Menu Configuration
page-title: Generating custom menus in Vaadin Flow
description: Collecting menu annotated routes for menu generation.
meta-description: Use MenuConfiguration to collect defined server and client routes for creating menus in Vaadin Flow.
order: 115
order: 17
---


Expand Down
2 changes: 1 addition & 1 deletion articles/flow/testing/ui-unit/spring.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class TestViewSecurityConfig {
@Bean
NavigationAccessControl navigationAccessControl() {
return new SpringNavigationAccessControl());
return new SpringNavigationAccessControl();
}
}
----
Expand Down
16 changes: 13 additions & 3 deletions articles/styling/lumo/lumo-style-properties/interaction.adoc
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: Interaction
page-title: How to use interaction properties in Lumo | Vaadin
description: Lumo style properties related to how interactions are indicated in an application, mainly by different mouse cursors.
meta-description: Learn about Lumo interaction properties to enhance the user experience with visual feedback in your Vaadin applications.
page-title: Interaction Properties in Lumo | Vaadin
description: Lumo style properties related to how interactions are indicated in an application.
meta-description: How Lumo interaction properties enhance the user experience with visual feedback in Vaadin applications.
order: 60
page-links:
- https://github.com/vaadin/web-components/blob/v{moduleNpmVersion:vaadin-lumo-styles}/packages/vaadin-lumo-styles/style.js[Source]
Expand All @@ -11,6 +11,11 @@ page-links:

= Lumo Interaction

The user may be made aware of the focus of an application with the use of a cursor, or with a focus ring. The Lumo properties may be set to improve the user experience with these visual clues, depending on the situation.


== Cursor

Lumo defines a CSS custom property that you can use to adjust the way in which your application signals clickable elements to users of pointer devices -- typically a mouse.

You can either follow the _web_ approach and use the pointer (i.e., hand) cursor for clickable items, or take the _desktop_ approach and use the default (i.e., arrow) cursor.
Expand All @@ -29,4 +34,9 @@ You can either follow the _web_ approach and use the pointer (i.e., hand) cursor
|===


[role="since:com.vaadin:[email protected]"]
== Pointer Focus Ring

By default, Vaadin components show a focus ring only when the user navigates using the keyboard. You can enable a focus ring for pointer devices by setting the `--lumo-input-field-pointer-focus-visible` custom property to `1`. This applies only to components with an input field, such as Text Field, Date Picker, etc.

[discussion-id]`4D15B095-CBCB-4E82-A82B-E5B2DA00EDE5`
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Add Modernization as a plugin:
<plugin>
<groupId>com.vaadin.addons.modernization</groupId>
<artifactId>mtk-maven-plugin</artifactId>
<version>2.0.11</version>
<version>2.0.13</version>
</plugin>
.
.
Expand Down
3 changes: 3 additions & 0 deletions frontend/demo/auth/LoginView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ export default function LoginView() {
opened
error={hasError.value}
noForgotPassword
onErrorChanged={(event) => {
hasError.value = event.detail.value;
}}
onLogin={async ({ detail: { username, password } }) => {
const { error } = await login(username, password);
hasError.value = Boolean(error);
Expand Down

0 comments on commit fad3958

Please sign in to comment.