diff --git a/articles/flow/advanced/browser-access.adoc b/articles/flow/advanced/browser-access.adoc index 82aa1a5c3e..dbe4aaa90a 100644 --- a/articles/flow/advanced/browser-access.adoc +++ b/articles/flow/advanced/browser-access.adoc @@ -33,21 +33,25 @@ UI.getCurrent().getPage().fetchCurrentURL(currentUrl -> { == Accessing Browser Information -During the initial HTTP request, Vaadin reads the user-agent information supplied by the browser and stores them in a [classname]`WebBrowser` instance, which is accessible from the current [classname]`VaadinSession`. +During the initial HTTP request, Vaadin reads the user-agent information supplied by the browser and stores it in a [classname]`WebBrowser` instance, which is accessible from the current [classname]`VaadinSession`. -Here’s an example how to get the `WebBrowser` instance and access some of the user-agent information: +Use [methodname]`getUserAgent()` to get the raw user-agent string. For structured browser detection (e.g., browser name, version, or operating system), use a parsing library such as https://github.com/ua-parser/uap-java[ua-parser/uap-java]. [source,java] ---- WebBrowser browser = VaadinSession.getCurrent().getBrowser(); -// Print the raw user-agent string -System.out.println(browser.getBrowserApplication()); -// Print some parsed browser details -System.out.println("Is Windows: " + browser.isWindows()); -System.out.println("Is Chrome: " + browser.isChrome()); -System.out.println("Major version: " + browser.getBrowserMajorVersion()); +String userAgent = browser.getUserAgent(); +// Use a parsing library for structured detection, for example: +// Parser parser = new Parser(); +// Client client = parser.parse(userAgent); +// String browserName = client.userAgent.family; // "Chrome" +// String os = client.os.family; // "Windows" ---- +[since:com.vaadin:vaadin@V25] +[NOTE] +The browser and OS detection methods in [classname]`WebBrowser` -- such as [methodname]`getBrowserApplication()`, [methodname]`isChrome()`, [methodname]`isWindows()`, and [methodname]`getBrowserMajorVersion()` -- are deprecated. Use [methodname]`getUserAgent()` with a parsing library instead. + == Getting the Extended Client-Side Details @@ -96,6 +100,44 @@ The parameter value is `null` for a parameter of type [classname]`Element` that The script is executed asynchronously, so you can't directly pass values back to the server. Instead, you can use the returned [classname]`PendingJavaScriptResult` instance to add a callback that's called when the result is available. +== Scrolling a Component into View + +You can scroll any component into the visible area of the browser window using [methodname]`scrollIntoView()`. This calls the browser's native `scrollIntoView()` on the component's element. + +.Scrolling a component into view +[source,java] +---- +component.scrollIntoView(); +---- + +Use [classname]`ScrollIntoViewOption` to control scrolling behavior and alignment: + +.Smooth scrolling +[source,java] +---- +component.scrollIntoView(ScrollIntoViewOption.Behavior.SMOOTH); +---- + +.Scrolling to align the component at the bottom of the viewport +[source,java] +---- +component.scrollIntoView(ScrollIntoViewOption.Block.END); +---- + +Options can be combined. [classname]`Behavior` controls the scrolling animation, [classname]`Block` controls vertical alignment, and [classname]`Inline` controls horizontal alignment. + +.Combining multiple options +[source,java] +---- +component.scrollIntoView( + ScrollIntoViewOption.Behavior.SMOOTH, + ScrollIntoViewOption.Block.END, + ScrollIntoViewOption.Inline.CENTER); +---- + +The available alignment values for both [classname]`Block` and [classname]`Inline` are `START`, `CENTER`, `END`, and `NEAREST`. + + == Browser Window Resize Events The [classname]`Page` class allows you to register a listener for events that affect the web page and the browser window in which the Vaadin UI lives. diff --git a/articles/flow/component-internals/element-api/calling-javascript.adoc b/articles/flow/component-internals/element-api/calling-javascript.adoc index 2e09c20783..cb41eb5d3f 100644 --- a/articles/flow/component-internals/element-api/calling-javascript.adoc +++ b/articles/flow/component-internals/element-api/calling-javascript.adoc @@ -124,4 +124,44 @@ If the return value is a JavaScript `Promise`, the client only sends the return // TODO What happens if the Promise is rejected? +=== Deserializing Generic Types with TypeReference + +The [methodname]`then()` method accepts a [classname]`Class` parameter for simple types, but this doesn't work for generic types like `List` due to Java type erasure. For these cases, use the Jackson [classname]`TypeReference` overloads. + +.Deserializing a JavaScript array into a `List` +[example] +==== +[source,java] +---- +getElement().executeJs("return this.getItems()") + .then(new TypeReference>() {}, + items -> { + // items is List + items.forEach(person -> + System.out.println(person.getName())); + }); +---- +==== + +An error handler can be provided as a second callback: + +[source,java] +---- +getElement().executeJs("return this.getItems()") + .then(new TypeReference>() {}, + items -> processItems(items), + error -> handleError(error)); +---- + +You can also use [methodname]`toCompletableFuture(TypeReference)` to get the result as a [classname]`CompletableFuture`: + +[source,java] +---- +CompletableFuture> future = getElement() + .executeJs("return this.getPersonMap()") + .toCompletableFuture( + new TypeReference>() {}); +---- + + [discussion-id]`AB7EDF45-DB22-4560-AF27-FF1DC6944482`