React Guide
This guideline uses create-react-app, React v17.0.2 and Yarn v1.22.10.
Install yarn.
npm install -g yarn
Initialize your project
To create a new app, you may choose one of the following methods:
npx
npx create-react-app my-app
yarn
yarn create react-app my-app
It will create a directory called my-app
inside the current folder. Inside that directory, it will generate the initial project structure and install the required dependencies.
Serve your app to check if the project is created correctly.
cd my-app
yarn start
Install EF elements and themes
Installs elements and themes.
yarn add @refinitiv-ui/elements
yarn add @refinitiv-ui/halo-theme
Import elements that you want to use and theme in src/index.js
. You can also import EF components and themes anywhere in react components but for the simplicity we'll import all at once.
import '@refinitiv-ui/elements/lib/loader';
import '@refinitiv-ui/elements/lib/button';
import '@refinitiv-ui/elements/lib/panel';
import '@refinitiv-ui/elements/lib/text-field';
import '@refinitiv-ui/elements/lib/password-field';
import '@refinitiv-ui/halo-theme/dark/imports/native-elements';
import '@refinitiv-ui/elements/lib/loader/themes/halo/dark';
import '@refinitiv-ui/elements/lib/button/themes/halo/dark';
import '@refinitiv-ui/elements/lib/panel/themes/halo/dark';
import '@refinitiv-ui/elements/lib/text-field/themes/halo/dark';
import '@refinitiv-ui/elements/lib/password-field/themes/halo/dark';
Use EF elements to create a simple login page. Replace the content in src/App.js
with the following code.
import React, { useState } from 'react';
import './App.css';
function App() {
const [title, setTitle] = useState('Hello!');
const [loading, setLoading] = useState(false);
function login() {
setLoading(true);
setTimeout(() => {
setTitle('Done!');
setLoading(false);
}, 2000);
}
return (
<ef-panel id="login-page" spacing>
{loading ? (
<ef-loader></ef-loader>
) : (
<>
<h1>{title}</h1>
<ef-text-field placeholder='Username'></ef-text-field>
<ef-password-field placeholder='Password'></ef-password-field>
<div id="button-group">
<ef-button onClick={login}>Login</ef-button>
<ef-button>Cancel</ef-button>
</div>
</>
)}
</ef-panel>
);
}
export default App;
And in src/App.css
#login-page {
display: flex;
flex-direction: column;
align-items: center;
width: 450px;
height: 200px;
margin: 40px auto;
}
#button-group {
margin: 10px 0;
}
Finally, starting your app and it should automatically open http://localhost:3000/
on your default browser.
yarn start
Using web components in React
Web components can be used in React just like any other HTML elements. However, there are a few differences to note.
class vs className
Web component uses class
attribute instead of className
.
function Panel() {
return (
<ef-panel class="container">
...
</ef-panel>
);
}
Attributes
Boolean
Boolean attributes such as disabled
, readonly
, checked
are set by the presence of the attribute itself, not the value. To represent a false
value in JSX, set the attribute's value to undefined
or null
or simply remove the attribute. This behavior is the same as HTML specifications.
Regardless of the value, the following code will disable the ef-text-field
.
<ef-text-field disabled></ef-text-field>
<ef-text-field disabled="true"></ef-text-field>
<ef-text-field disabled="false"></ef-text-field>
<ef-text-field disabled={true}></ef-text-field>
<ef-text-field disabled={false}></ef-text-field>
The following will omit disabled
attribute and enable ef-text-field
.
<ef-text-field></ef-text-field>
<ef-text-field disabled={undefined}></ef-text-field>
Array and Object
React only allows primitive data to be passed through attributes. For Array
and Object
, you can either pass data through element's property or use JSON.stringify()
to parse the data before passing to attribute.
<ef-sparkline data={JSON.stringify([-2, -3, 4])}></ef-sparkline>
or
function SparklineChart() {
const chartRef = React.useRef();
React.useLayoutEffect(() => {
if (chartRef.current) {
chartRef.current.data = [-2, -3, 4];
}
}, [chartRef]);
return <ef-sparkline ref={chartRef}></ef-sparkline>;
}
Events
Use ref
to access and store DOM element, then add an event-listener inside useLayoutEffect
which fires synchronously after the DOM mutation (or componentDidMount
in class component). Finally, don't forget to unsubscribe from event-listener when component unmounts.
function App() {
const textFieldRef = React.useRef();
const [value, setValue] = React.useState('');
React.useLayoutEffect(() => {
const handleChange = (event) => {
setValue(event.detail.value);
};
const { current } = textFieldRef;
if (current) {
current.value = value; // update element's value
current.addEventListener('value-changed', handleChange);
}
return () => current.removeEventListener('value-changed', handleChange); // unsubscribe
}, [value, textFieldRef]);
return <ef-text-field ref={textFieldRef}></ef-text-field>;
}
Develop the application on IE11 (or legacy browsers)
Legacy browser does not support Web Component and ES2015.
By default create-react-app
does not provide the polyfills. You will have to configure your application to include all necessary polyfills so your app can work on legacy browsers. Polyfills should load at earliest, imports the polyfills at the very top of src\index.js
and followed by elements and themes.
yarn add react-app-polyfill
yarn add @refinitiv-ui/polyfills
@refinitiv-ui/polyfills/minimal
provides polyfills for custom components without any polyfills for ES2015 features so you can use it with react-app-polyfill.
For more details about react-app-polyfill, see here.
Import them before EF polyfills.
import 'react-app-polyfill/ie11';
import '@refinitiv-ui/polyfills/minimal';
Once you've included the polyfills, it's still not working when you open your app, http://localhost:3000/
, on IE11
. This is because development environment is set to run in modern browsers as it's easier for developers to debug.
To run a development server on IE11, open package.json
and add IE 11
to development
section at broswerslist
configuration.
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version",
+ "IE 11"
]
}
For production build, the configuration already supports IE11
. You can see the list of browsers it covers by running command:
npx browserslist
You'll see that IE11 is already included the list. You can update the configuration to be suitable with browsers that your app needs to support. For more detail, see browserslist.
That's all for now. Contact us at RefinitivUIDev@refinitiv.com, if you need any extra help!