A React Wrapper around UI5 Web Components
Source: https://2020.stateofjs.com/en-US/technologies/front-end-frameworks/
A JavaScript library for building user interfaces
Disclaimer: This content is copied from the React Website, https://reactjs.org
function MyComponent() {
return <button onClick={() => alert("Hello World!")}>Click Me!</button>;
}
The current versions of React (react 16
and react 17
) both have some shortcomings in using CustomElements
in your
React components:
boolean
attributesboolean
attributesimport "@ui5/webcomponents/dist/Button";
function MyComponent() {
return (
<>
<ui5-button
onClick={() => alert("I'll be there onClick!")}
disabled={false}
>
Click me!
</ui5-button>
<ui5-button
onClick={() => alert("I will never show up!")}
disabled={true}
>
But you can't click me!
</ui5-button>
</>
);
}
import "@ui5/webcomponents/dist/Button";
function MyComponent() {
const booleanPropsBtn1 = {};
const booleanPropsBtn2 = {};
const button1ShouldBeDisabled = false;
const button2ShouldBeDisabled = true;
if (button1ShouldBeDisabled === true) {
booleanPropsBtn1.disabled = true;
}
if (button2ShouldBeDisabled === true) {
booleanPropsBtn2.disabled = true;
}
return (
<>
<ui5-button
onClick={() => alert("I'll be there onClick!")}
{...booleanPropsBtn1}
>
Click me!
</ui5-button>
<ui5-button
onClick={() => alert("I will never show up!")}
{...booleanPropsBtn2}
>
But you can't click me!
</ui5-button>
</>
);
}
import "@ui5/webcomponents/dist/Calendar";
function MyComponent() {
return (
<ui5-calendar
onSelectedDatesChange={(e) => {
e.detail.dates.forEach((d) => alert(new Date(d * 1000)));
}}
/>
);
}
import "@ui5/webcomponents/dist/Calendar";
function MyComponent() {
const ref = useRef();
useEffect(() => {
const currentRef = ref.current;
const handler = (e) => {
e.detail.dates.forEach((d) => {
alert(new Date(d * 1000));
});
};
// bind the event handler after the component has mounted
if (currentRef) {
currentRef.addEventListener("selected-dates-change", handler);
}
// remove the event handler before component unmounts to free up memory
return () => {
if (currentRef) {
currentRef.removeEventListener("selected-dates-change", handler);
}
};
}, []);
return <ui5-calendar ref={ref} />;
}
Let's pretend that we have this CSS definition available on our website:
<style>
.textColorRed {
color: red;
}
</style>
You can add it to any HTML Element by using the className
prop:
function MyComponent() {
return <span className="textColorRed">Click Me!</span>;
}
className
on Custom Elements doesn't workimport "@ui5/webcomponents/dist/Label";
function MyComponent() {
return <ui5-label className="textColorRed">I'm a text!</ui5-label>;
}
You have to use the plain HTML class
prop for achieving the same behaviour for Custom Elements:
import "@ui5/webcomponents/dist/Label";
function MyComponent() {
return <ui5-label class="textColorRed">I'm a text!</ui5-label>;
}
ObjectPage
) and charts built on top of UI5 Web ComponentsOur Wrapper components are hiding the complexity of dealing with Custom Elements in React and let you use the UI5 Web Components in React as if they were "regular" React Components.
import "@ui5/webcomponents/dist/Button";
function MyComponent() {
const booleanPropsBtn1 = {};
const booleanPropsBtn2 = {};
const button1ShouldBeDisabled = false;
const button2ShouldBeDisabled = true;
if (button1ShouldBeDisabled === true) {
booleanPropsBtn1.disabled = true;
}
if (button2ShouldBeDisabled === true) {
booleanPropsBtn2.disabled = true;
}
return (
<>
<ui5-button
onClick={() => alert("I'll be there onClick!")}
{...booleanPropsBtn1}
>
Click me!
</ui5-button>
<ui5-button
onClick={() => alert("I will never show up!")}
{...booleanPropsBtn2}
>
But you can't click me!
</ui5-button>
</>
);
}
import { Button } from "@ui5/webcomponents-react";
function MyComponent() {
return (
<>
<Button
onClick={() => alert("I'll be there onClick!")}
disabled={false}
>
Click me!
</Button>
<Button
onClick={() => alert("I will never show up!")}
disabled={true}
>
But you can't click me!
</Button>
</>
);
}
import "@ui5/webcomponents/dist/Calendar";
function MyComponent() {
const ref = useRef();
useEffect(() => {
const currentRef = ref.current;
const handler = (e) => {
e.detail.dates.forEach((d) => {
alert(new Date(d * 1000));
});
};
// bind the event handler after the component has mounted
if (currentRef) {
currentRef.addEventListener("selected-dates-change", handler);
}
// remove the event handler before component unmounts to free up memory
return () => {
if (currentRef) {
currentRef.removeEventListener("selected-dates-change", handler);
}
};
}, []);
return <ui5-calendar ref={ref} />;
}
import { Calendar } from "@ui5/webcomponents-react";
function MyComponent() {
return (
<Calendar
onSelectedDatesChange={(e) => {
e.detail.dates.forEach((d) => alert(new Date(d * 1000)));
}}
/>
);
}
import "@ui5/webcomponents/dist/Label";
function MyComponent() {
return <ui5-label class="textColorRed">I'm a text!</ui5-label>;
}
import { Label } from "@ui5/webcomponents-react";
function MyComponent() {
return <Label className="textColorRed">I'm a text!</Label>;
}
In addition to fixing the className
issue, our components are also passing through all aria-
, data-
and event handler
attributes.