This page documents the web component layer that wraps PatternFly React charts as custom HTML elements. This layer enables Java code to instantiate and manipulate React-based charts through a standard web component interface.
For information about the overall chart architecture and data flow, see Chart Architecture Overview. For the Java-side API that consumes these web components, see Chart Java API. For the build and publishing process, see Chart Build and Publishing.
The chart web components are implemented using Lit as the base web component library and manage React component lifecycle internally. All chart web components extend the ReactWrapperElement base class, which provides common functionality for bridging web component attributes/properties to React props and managing the React rendering lifecycle.
Sources: charts/npm/src/react-wrapper.js16-393 charts/npm/src/components/pfj-chart-bullet.js1-196
The ReactWrapperElement class (defined in charts/npm/src/react-wrapper.js) provides the foundation for all chart web components. It extends LitElement and manages the complete lifecycle of wrapping React components as web components.
Sources: charts/npm/src/react-wrapper.js71-393 charts/npm/src/components/pfj-chart-bullet.js19-193
The base class maintains several critical pieces of state:
| Property | Type | Purpose |
|---|---|---|
_root | ReactRoot | React 18+ root for rendering components |
_container | HTMLElement | DOM container element for React rendering |
_observer | MutationObserver | Monitors attribute changes to trigger re-renders |
| Common properties | Various | Chart-specific properties (data, width, height, labels, etc.) |
Sources: charts/npm/src/react-wrapper.js83-106
The lifecycle management ensures proper coordination between Lit's web component lifecycle and React's rendering lifecycle:
Sources: charts/npm/src/react-wrapper.js166-224
The firstUpdated method (charts/npm/src/react-wrapper.js166-194) handles initial setup:
.container divReactWrapperElementcreateRoot(this._container)MutationObserver to watch for attribute and child changes_renderReact() to perform initial renderMutationObserver to notify the parent when attributes changeThe disconnectedCallback method (charts/npm/src/react-wrapper.js196-206) ensures proper cleanup:
MutationObserverSources: charts/npm/src/react-wrapper.js166-206
The web component supports two ways to configure charts: HTML attributes and JavaScript properties. The parseAttrValue utility function handles conversion from string attributes to appropriate JavaScript types:
Sources: charts/npm/README.md33-64 charts/npm/src/react-wrapper.js23-41
Each common property (data, height, width, labels, etc.) has a getter and setter pair that:
_data)_notifyChange() when set, which triggers a re-renderFor example, the data property:
Sources: charts/npm/src/react-wrapper.js236-243
The _notifyChange method (charts/npm/src/react-wrapper.js214-223) implements different behavior based on whether the element is slotted:
_renderReact() directlySources: charts/npm/src/react-wrapper.js214-223
The _commonProps method (charts/npm/src/react-wrapper.js344-392) builds a props object for React by:
this._data)parseAttrValueThis enables both declarative HTML usage and imperative JavaScript manipulation:
Sources: charts/npm/src/react-wrapper.js344-392 charts/npm/demo.html112-142
The _renderReact method (charts/npm/src/react-wrapper.js127-140) is the central rendering method:
Sources: charts/npm/src/react-wrapper.js127-140
The rendering process:
_buildPropsFromAttributes (charts/npm/src/react-wrapper.js44-53)_commonPropsgetReactComponent() - Subclass provides [ReactComponent, extraProps] pairReact.createElement(Component, props, ...children)_root.render(element)Sources: charts/npm/src/react-wrapper.js127-140
Certain React props are filtered out because they expect React components as values, which cannot be passed through web component attributes. The disallowed set is defined at charts/npm/src/react-wrapper.js58-67:
These props are removed during rendering at charts/npm/src/react-wrapper.js134-136
Sources: charts/npm/src/react-wrapper.js58-67 charts/npm/src/react-wrapper.js134-136
Each chart type is implemented as a subclass of ReactWrapperElement that defines chart-specific properties and returns the corresponding React component.
Sources: charts/npm/README.md9-15 charts/npm/src/components/pfj-chart-bullet.js1-196
The bullet chart component (charts/npm/src/components/pfj-chart-bullet.js) demonstrates the typical implementation pattern:
Constructor (charts/npm/src/components/pfj-chart-bullet.js21-34): Initializes chart-specific properties as undefined:
getReactComponent (charts/npm/src/components/pfj-chart-bullet.js36-93): Returns the React component class and chart-specific props:
Property accessors (charts/npm/src/components/pfj-chart-bullet.js95-193): Each property follows the same pattern:
Custom element registration (charts/npm/src/components/pfj-chart-bullet.js195):
Sources: charts/npm/src/components/pfj-chart-bullet.js1-196
Some chart components support nesting other chart components as children using the slot mechanism. The most common use case is nesting a <pfj-chart-donut-utilization> inside a <pfj-chart-donut-threshold>.
Sources: charts/npm/src/react-wrapper.js166-194 charts/npm/src/react-wrapper.js208-212
When a ReactWrapperElement detects it is slotted into another ReactWrapperElement (charts/npm/src/react-wrapper.js208-212):
MutationObserver to notify the parent when its attributes change_renderReact method calls _getReactChildren() to convert slotted elements to React elementsThe _getReactChildren method (charts/npm/src/react-wrapper.js142-162) implements the conversion:
Sources: charts/npm/src/react-wrapper.js142-162
The HTML structure:
The rendering flow:
<pfj-chart-donut-threshold> creates a React root<pfj-chart-donut-utilization> detects it is slotted and does NOT create a root_renderReact calls _getReactChildren()React.createElement(ChartDonutUtilization, childProps)React.createElement(ChartDonutThreshold, parentProps, childElement)Sources: charts/npm/README.md50-64 charts/npm/demo.html78-94
The web component uses a MutationObserver to detect changes and trigger re-renders.
Sources: charts/npm/src/react-wrapper.js184-185 charts/npm/src/react-wrapper.js214-223
For standalone elements (charts/npm/src/react-wrapper.js184-192):
This watches for:
attributes: true - Attribute changes on the elementchildList: true - Children being added/removedsubtree: true - Changes in descendant nodesThe observer also listens for slotchange events to re-render when slotted children change.
For slotted elements (charts/npm/src/react-wrapper.js174-179):
This only watches for attribute changes and notifies the parent to re-render.
Sources: charts/npm/src/react-wrapper.js174-192
The showcase application imports and uses the chart web components:
Import statement in showcase/src/web/main.js19:
This single import registers all chart web components with the browser's custom element registry.
Java code then instantiates and configures the elements:
The DonutElement interface is defined in Java with JSInterop annotations, and the externs file (charts/src/main/resources/META-INF/externs/charts.externs.js) ensures property names are preserved during J2CL compilation.
Sources: showcase/src/web/main.js16-20 charts/npm/README.md1-87
The chart web component layer provides:
| Feature | Implementation |
|---|---|
| Base class | ReactWrapperElement extends LitElement |
| React integration | React root managed per standalone element |
| Property handling | Dual attribute/property API with type conversion |
| Nested components | Slot-based parent-child rendering |
| Change detection | MutationObserver for attributes and children |
| Lifecycle management | Coordinated Lit and React lifecycles |
| Type safety | Property getters/setters with _notifyChange pattern |
The architecture enables Java developers to work with React-based charts through a clean web component API while the wrapper handles all React-specific complexity transparently.
Sources: charts/npm/src/react-wrapper.js1-394 charts/npm/src/components/pfj-chart-bullet.js1-196 charts/npm/README.md1-87
Refresh this wiki