Skip to content

Commit

Permalink
Merge branch 'latest' into feat/hilla/endpointrequestinit
Browse files Browse the repository at this point in the history
  • Loading branch information
russelljtdyer authored Feb 28, 2025
2 parents 256f744 + ed987ef commit 3a5df27
Show file tree
Hide file tree
Showing 30 changed files with 2,674 additions and 2,169 deletions.
1 change: 1 addition & 0 deletions .github/styles/config/vocabularies/Docs/accept.txt
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ TypeScript
[uU]nparsable
[uU]nrendered
[uU]nsecure
[uU]nserializable
(?-i)Vaadin
[vV]alidate
[vV]alidators?
Expand Down
8 changes: 8 additions & 0 deletions articles/components/grid/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,14 @@ ifdef::react[]
----
include::{root}/frontend/demo/component/grid/react/grid-data-provider.tsx[render,tags=snippet,indent=0,group=React]
----
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/grid/GridPersonService.java[render,tags=snippet,indent=0,group=React]
----
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/grid/GridPersonRepository.java[render,tags=snippet,indent=0,group=React]
----
endif::[]
--

Expand Down
108 changes: 104 additions & 4 deletions articles/components/horizontal-layout/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -124,32 +124,44 @@ endif::[]

== Horizontal Alignment

Components in a Horizontal Layout can be left-aligned, centered or right-aligned. You can also position components by specifying how the excess space in a layout is distributed among them.
There are two ways to align items horizontally: _individual alignment_ of items, and _justification_. These two methods cannot be used simultaneously.


[role="since:com.vaadin:vaadin@V24.7"]
=== Aligning Individual Items

Each item in the layout can be grouped to the start, center and end of the layout.

[.example]
--

ifdef::lit[]
[source,typescript]
----
include::{root}/frontend/demo/component/horizontal-layout/horizontal-layout-horizontal-alignment.ts[render,tags=snippet,indent=0,group=Lit]
include::{root}/frontend/demo/component/horizontal-layout/horizontal-layout-slots.ts[render,tags=snippet,indent=0,group=Lit]
----
endif::[]

ifdef::flow[]
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/horizontallayout/HorizontalLayoutHorizontalAlignment.java[render,tags=layout,indent=0,group=Flow]
include::{root}/src/main/java/com/vaadin/demo/component/horizontallayout/HorizontalLayoutSlots.java[render,tags=snippet,indent=0,group=Flow]
----
endif::[]

ifdef::react[]
[source,tsx]
----
include::{root}/frontend/demo/component/horizontal-layout/react/horizontal-layout-horizontal-alignment.tsx[render,tags=snippet,indent=0,group=React]
include::{root}/frontend/demo/component/horizontal-layout/react/horizontal-layout-slots.tsx[render,tags=snippet,indent=0,group=React]
----
endif::[]
--


=== Justification

Justification modes determine how items in the layout are distributed within the available space. Six justification modes are available:

|===
|Value |Description

Expand All @@ -173,6 +185,32 @@ endif::[]
|===


[.example]
--

ifdef::lit[]
[source,typescript]
----
include::{root}/frontend/demo/component/horizontal-layout/horizontal-layout-horizontal-alignment.ts[render,tags=snippet,indent=0,group=Lit]
----
endif::[]

ifdef::flow[]
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/horizontallayout/HorizontalLayoutHorizontalAlignment.java[render,tags=layout,indent=0,group=Flow]
----
endif::[]

ifdef::react[]
[source,tsx]
----
include::{root}/frontend/demo/component/horizontal-layout/react/horizontal-layout-horizontal-alignment.tsx[render,tags=snippet,indent=0,group=React]
----
endif::[]
--


== Spacing

Spacing is used to create space among components in the same layout. Spacing can help prevent misclicks and distinguish content areas.
Expand Down Expand Up @@ -267,6 +305,38 @@ endif::[]

--

[since:com.vaadin:vaadin@V24.7]#Alternatively, the spacing can be set to a custom value:#

[.example]
--
ifdef::lit[]
[source,html]
----
<source-info group="Lit"></source-info>
<vaadin-horizontal-layout style="gap: 12px">
</vaadin-horizontal-layout>
----
endif::[]

ifdef::flow[]
[source,java]
----
<source-info group="Flow"></source-info>
HorizontalLayout layout = new HorizontalLayout();
layout.setSpacing(12, Unit.PIXELS);
----
endif::[]

ifdef::react[]
[source,tsx]
----
<source-info group="React"></source-info>
<HorizontalLayout style={{ gap: '12px' }}>
</HorizontalLayout>
----
endif::[]

--

== Padding

Expand Down Expand Up @@ -358,6 +428,36 @@ endif::[]
--


=== Wrapping Horizontally Aligned Items

Wrapping may not behave as desired when combined with either of the two <<#horizontal-alignment,horizontal alignment>> methods. One common solution is group items that should wrap together into sub-layouts:

[.example]
--

ifdef::lit[]
[source,typescript]
----
include::{root}/frontend/demo/component/horizontal-layout/horizontal-layout-slots-wrapping.ts[render,tags=snippet,indent=0,group=Lit]
----
endif::[]

ifdef::flow[]
[source,java]
----
include::{root}/src/main/java/com/vaadin/demo/component/horizontallayout/HorizontalLayoutSlotsWrapping.java[render,tags=snippet,indent=0,group=Flow]
----
endif::[]

ifdef::react[]
[source,tsx]
----
include::{root}/frontend/demo/component/horizontal-layout/react/horizontal-layout-slots-wrapping.tsx[render,tags=snippet,indent=0,group=React]
----
endif::[]
--


== Expanding Items

Components can be made to expand and take up any excess space a layout may have.
Expand Down
2 changes: 1 addition & 1 deletion articles/components/spreadsheet/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ The Vaadin Spreadsheet has a few inherent limitations. Below is a list of them:
* No provided toolbars, menus, or other controls for formatting cells.
* Limited support for the older XSL formats.
* Constraints related to Apache POI, such as importing and exporting Excel files.
* The component is not serializable due to the internal usage of Apache POI. The `@PreserveOnRefresh` annotation and session replication with Kubernetes Kit are not supported when using Spreadsheet.
* The component is not serializable due to the internal usage of Apache POI. The `@PreserveOnRefresh` annotation is not supported when using Spreadsheet. Session replication with Kubernetes Kit requires to use <<{articles}/tools/kubernetes/session-replication#unserializable-component-wrapper,UnserializableComponentWrapper>>.
* The SUBTOTAL formula is limited to aggregate functions that do not ignore hidden values (i.e., function codes from 1 to 7, as well as 9) because they are not implemented in Apache POI.
* Strict OOXML format is not supported by Apache POI.
* No support for theming the component the same way as other Vaadin components.
Expand Down
32 changes: 32 additions & 0 deletions articles/components/vertical-layout/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,38 @@ endif::[]

--

[since:com.vaadin:vaadin@V24.7]#Alternatively, the spacing can be set to a custom value:#

[.example]
--
ifdef::lit[]
[source,html]
----
<source-info group="Lit"></source-info>
<vaadin-vertical-layout style="gap: 12px">
</vaadin-vertical-layout>
----
endif::[]

ifdef::flow[]
[source,java]
----
<source-info group="Flow"></source-info>
VerticalLayout layout = new VerticalLayout();
layout.setSpacing(12, Unit.PIXELS);
----
endif::[]

ifdef::react[]
[source,tsx]
----
<source-info group="React"></source-info>
<VerticalLayout style={{ gap: '12px' }}>
</VerticalLayout>
----
endif::[]

--

== Padding

Expand Down
2 changes: 1 addition & 1 deletion articles/styling/legacy/material-theme/color.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ order: 20
---


= Material Color
= [deprecated:com.vaadin:vaadin@V24.7]#Material Color#
:toclevels: 2

See the "Material Design" documentation for https://material.io/design/color/the-color-system.html[the color system,window=_blank] to learn more about creating and applying a consistent color theme.
Expand Down
15 changes: 13 additions & 2 deletions articles/styling/legacy/material-theme/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,24 @@ order: 10
---


= Material Theme
= [deprecated:com.vaadin:vaadin@V24.7]#Material Theme#

pass:[<!-- vale Vaadin.Versions = NO -->]
pass:[<!-- vale Vaadin.Will = NO -->]

.The Material theme will be removed in Vaadin 25.
[WARNING]
====
Don't start a new project using the Material theme. Existing projects should consider migrating to the Lumo theme or the upcoming Aura theme in Vaadin 25.
====
pass:[<!-- vale Vaadin.Will = YES -->]
pass:[<!-- vale Vaadin.Versions = YES -->]

In addition to the Lumo theme, Vaadin components include a built-in _Material_ theme, inspired by the original Material Design system by Google.

Although this theme is no longer actively developed, it is still supported in Vaadin 24 for legacy purposes, but not recommended for new applications.

The theme can be applied using the @Theme annotation:
The theme can be applied using the `@Theme` annotation:

[source,java]
----
Expand Down
2 changes: 1 addition & 1 deletion articles/styling/legacy/material-theme/typography.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ order: 10
---


= Material Typography
= [deprecated:com.vaadin:vaadin@V24.7]#Material Typography#

See the "Material Design" documentation for https://material.io/design/typography/the-type-system.html[the type system,window=_blank] to learn about creating and applying a consistent typographic theme.

Expand Down
73 changes: 72 additions & 1 deletion articles/tools/kubernetes/session-replication.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ For more information on serialization process, consult the Java documentation on

The following sections contain best practices on how to code a fully serializable Vaadin application.


=== Collaboration Kit

If you're using Collaboration Kit in an application, you may need to follow some <<{articles}/tools/collaboration/advanced/serialization#,specific serialization instructions>>.


=== Serializable Object as UI Component Members

When writing a component, make sure that all of its non-transient members implement [classname]`Serializable`.
Expand Down Expand Up @@ -273,6 +275,75 @@ When a serialization or a deserialization error happens, Kubernetes Kit provides
The `SessionSerializationCallback` interface also provides the `onSerializationSuccess()` and `onDeserializationSuccess()` callback methods which can be used to add custom steps after a successful serialization or deserialization in the same way as for the error callbacks.


=== Unserializable Component Wrapper

A https://github.com/vaadin/kubernetes-kit/blob/main/kubernetes-kit-starter/src/main/java/com/vaadin/kubernetes/starter/sessiontracker/UnserializableComponentWrapper.java[wrapper component] that allows an otherwise unserializable [classname]`com.vaadin.flow.component.Component` to be serialized and deserialized using the provided serializer and deserializer functions.

The unserializable component wrapper should only be used in cases where there's no other option. The preferred way is to make sure that your own components are fully serializable.

During serialization, the serializer generates a serializable state object from the wrapped component. This state object is intended to store serializable and cacheable properties of the component. Upon deserialization, the deserializer reconstructs the component from scratch using the state object, after the entire object graph has been restored. Developers need to ensure the necessary component properties are properly persisted and restored. Also, the component listeners need to be registered again.

Unserializable components are temporarily removed from the component tree during serialization and reinserted after the serialization is completed. Any [classname]`com.vaadin.flow.component.UI` changes caused by their removal and re-addition are silently ignored.

[NOTE]
Any attach or detach listeners registered on the wrapped component are still triggered.

Below is an example using the unserializable component wrapper to wrap a [classname]`com.vaadin.flow.component.spreadsheet.Spreadsheet` component which is not fully serializable:

[source,java]
----
class SpreadsheetView extends VerticalLayout {
public SpreadsheetView() {
setSizeFull();
Spreadsheet spreadsheet = new Spreadsheet();
spreadsheet.createCell(1, 0, "Nicolaus");
spreadsheet.createCell(1, 1, "Copernicus");
configureSpreadsheet(spreadsheet);
var wrapper = new UnserializableComponentWrapper<>(spreadsheet,
SpreadsheetView::serializer, SpreadsheetView::deserializer);
addAndExpand(wrapper);
}
private static WorkbookData serializer(Spreadsheet sheet) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
sheet.write(baos);
String selection = Optional
.ofNullable(sheet.getCellSelectionManager()
.getSelectedCellRange())
.map(CellRangeAddress::formatAsString).orElse(null);
return new WorkbookData(baos.toByteArray(), selection);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private static Spreadsheet deserializer(WorkbookData data) {
try {
Spreadsheet sheet = new Spreadsheet(
new ByteArrayInputStream(data.data()));
if (data.selection() != null) {
sheet.setSelection(data.selection());
}
configureSpreadsheet(sheet);
return sheet;
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
private static void configureSpreadsheet(Spreadsheet sheet) {
sheet.setLocale(Locale.getDefault());
sheet.setWidth("800px");
}
private record WorkbookData(byte[] data,
String selection) implements Serializable {
}
}
----


== Session Replication Issues

Despite applying the mentioned tips, session replication still may fail because of issues during serialization or deserialization.
Expand All @@ -284,7 +355,7 @@ Common issues with serialization and deserialization are presented in the follow

=== SerializedLambda ClassCastException

A common Vaadin application extensively uses lambda expression for components listeners, binder, etc. When serializing and deserializing lambda expressions, it may happen to face [classname]`ClassCastException` with cryptic messages. For instance, `SerializedLambda cannot be cast to class <className>` on serialization, nor can `SerializedLambda be assigned to field <fieldName> of type <className>` on deserialization.
A common Vaadin application extensively uses lambda expression for components listeners, binder, etc. When serializing and deserializing lambda expressions, it may happen to face [classname]`ClassCastException` with cryptic messages. For instance, `SerializedLambda` cannot be cast to class `<className>` on serialization, nor can `SerializedLambda` be assigned to field `<fieldName>` of type `<className>` on deserialization.

Usually, the cause is a self reference. The lambda expression captures an object instance, but the expression is itself a member of the object graph of the captured object.

Expand Down
Loading

0 comments on commit 3a5df27

Please sign in to comment.