Skip to content

Commit 332a269

Browse files
caaladorZheSun88russelljtdyerjouni
authored
feat: add documentation for Flow in React (vaadin#3488)
* feat: add documentation for Flow in React Add documentation on using Flow components inside a React component. * Minor changes to wording * First pass at editing document touched. * Second pass at editing document touched. * Update source type Co-authored-by: Jouni Koivuviita <[email protected]> * Apply suggestions from code review Co-authored-by: Jouni Koivuviita <[email protected]> --------- Co-authored-by: Zhe Sun <[email protected]> Co-authored-by: Russell J.T. Dyer <[email protected]> Co-authored-by: Jouni Koivuviita <[email protected]>
1 parent 1190a05 commit 332a269

File tree

1 file changed

+66
-4
lines changed

1 file changed

+66
-4
lines changed

articles/flow/integrations/react.adoc

Lines changed: 66 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ order: 20
66

77
= [since:com.vaadin:[email protected]]#Using React Components in Flow#
88

9-
https://reactjs.org/[React] is a popular JS-based frontend UI library with a wide adoption and many components. This documentation page explains how to integrate existing React components with Flow by using an intermediate adapter Web Component, and then using it in Java applications.
9+
https://reactjs.org/[React] is a popular JS-based frontend UI library with many components and a wide adoption. This documentation page explains how to integrate existing React components with Flow by using an intermediate adapter Web Component, and then using it in Java applications.
1010

1111
This integration involves two parts: creating a Java class for the server-side adapter component; and a client-side adapter counterpart with TypeScript and React. For examples here, the https://omgovich.github.io/react-colorful/[React Colorful] color picker component is used.
1212

@@ -20,12 +20,12 @@ For the server-side part of the integration, create a Java class that extends fr
2020
----
2121
include::../../../src/main/java/com/vaadin/demo/flow/integration/react/RgbaColorPicker.java[tags=annotations]
2222
----
23-
<1> Since this will integrate a third-party React component, the [annotationname]`@NpmPackage` annotation is added to get it installed from npm.
23+
<1> Since this will integrate a third-party React component, the [annotationname]`@NpmPackage` annotation is added to have it installed from npm.
2424
<2> The [annotationname]`@Tag` annotation defines the DOM element name of the adapter Web Component (see below).
2525
<3> The client-side part of the integration (i.e., the adapter Web Component) is yet to be defined and implemented in TypeScript. Therefore, you'll need a separate file for it. Although this file will be created later, the [annotationname]`@JsModule` annotation is added here to import it.
2626

2727

28-
=== Java and React States Synchronized
28+
=== Java & React States Synchronized
2929

3030
The Web Component adapter allows the state to be sent from Java to React and back by using named properties and events in the intermediate Web Component. On the server side, the `ReactAdapterComponent` class provides the following APIs for synchronizing the state with the adapter Web Component:
3131

@@ -105,7 +105,7 @@ include::{root}/frontend/demo/flow/integration/react/rgba-color-picker.tsx[tags=
105105
The `RenderHooks` render callback argument provides the following methods:
106106

107107
- [methodname]`useState<T>(string)` method defines and uses a named state JS property of the adapter Web Component; and
108-
- [methodname]`useCustomEvent<T | undefined>(string, CustomEventInit<T>)` method returns a simple to use callback that dispatches a Custom Event with the given name on the adapter Web Component:
108+
- [methodname]`useCustomEvent<T | undefined>(string, CustomEventInit<T>)` method returns a simple-to-use callback that dispatches a Custom Event with the given name on the adapter Web Component:
109109

110110
.Firing a CustomEvent
111111
[source,jsx]
@@ -146,3 +146,65 @@ public void addPersonDataUpdateListener() {
146146
}).addEventData("event.detail");
147147
}
148148
----
149+
150+
151+
== Adding Flow Components to React Component
152+
153+
It's possible to put Flow [classname]`Component` elements inside a React component implemented with [classname]`ReactAdapterElement`.
154+
155+
You could generate a simple [classname]`RouterLayout` in React that has a navigation menu and the Flow route content on the right side. See <<../routing/layout#, RouterLayout Interface>> for more information.
156+
157+
Create a [classname]`ReactAdapterComponent` that implements the [interfacename]`RouterLayout` interface so that the showRouterLayoutContent is appended into the content element from [methodname]`getContentElement(String)`.
158+
159+
[classname]`RouterLinks` are added to a Div that's bound to the `menu` content element on the client.
160+
161+
.Server Router Layout
162+
[source,java]
163+
----
164+
@JsModule("./ReactRouterLayout.tsx")
165+
@Tag("react-router-layout")
166+
public class ReactRouterLayout extends ReactAdapterComponent implements RouterLayout {
167+
168+
public ReactRouterLayout() {
169+
Div links = new Div(
170+
new RouterLink("Main view", MainView.class),
171+
new Div(),
172+
new RouterLink("Information", InfoView.class)
173+
);
174+
links.getStyle().setMargin("10px");
175+
getContentElement("menu").appendChild(links.getElement());
176+
}
177+
178+
@Override
179+
public void showRouterLayoutContent(HasElement content) {
180+
if (content != null) {
181+
// Bind the flow element to the 'flowContent' element on the client
182+
getContentElement("flowContent")
183+
.appendChild(Objects.requireNonNull(content.getElement()));
184+
}
185+
}
186+
}
187+
188+
----
189+
190+
On the client, there are two places for Flow components to bind: one for `menu` and one for `flowContent`, using the [methodname]`userContent(string)`.
191+
192+
.Client Router Layout
193+
[source,jsx]
194+
----
195+
class ReactRouterLayoutElement extends ReactAdapterElement {
196+
protected render(hooks: RenderHooks): React.ReactElement | null {
197+
// create content element for name attribute 'menu'
198+
const menu = hooks.useContent('menu');
199+
// create content element for name attribute 'flowContent'
200+
const content = hooks.useContent('flowContent');
201+
202+
return §div style={{display: 'flex', flex: 1, flexDirection: 'row', height: '100%'}}>
203+
<div style={{flex: 1}}>{menu}</div>
204+
<div style={{flex: 5}}>{content}</div>
205+
</div>;
206+
}
207+
}
208+
209+
customElements.define('react-router-layout', ReactRouterLayoutElement);
210+
----

0 commit comments

Comments
 (0)