Skip to main content

React Components

Fanoni maintains a library of React components which we use in the Fanoni app and are open source. We support use of our React component library in third party apps as well.

The best way to get started is to try one of the Fanoni example apps:

Or, you can try our full-featured patient demo called Foo Medical.

Prerequisites

As the name implies, Fanoni React components are built with React. Fanoni requires React 18+.

npm i -D react react-dom

Fanoni React components are built with Mantine, which is a fantastic library for building functional accessible web applications. Fanoni uses Mantine version 7+.

npm i -D @mantine/core @mantine/hooks @mantine/notifications

Fanoni and Mantine both use PostCSS for CSS processing. Mantine provides a PostCSS preset for common configuration.

npm i -D postcss postcss-preset-mantine

While not strictly required, Fanoni recommends using React Router for client side routing. Fanoni uses React Router version 6+.

npm i -D react-router

And then finally you can install Fanoni React components:

npm i -D @medplum/core @medplum/react

Getting Started

If you are not familiar with Mantine, you may want to start with the Mantine Getting Started guide.

There are a few important steps.

PostCSS Configuration

Create a postcss.config.mjs file in the root of your project:

import mantinePreset from 'postcss-preset-mantine';
import simpleVars from 'postcss-simple-vars';

const config = {
plugins: [
mantinePreset(),
simpleVars({
variables: {
'mantine-breakpoint-xs': '36em',
'mantine-breakpoint-sm': '48em',
'mantine-breakpoint-md': '62em',
'mantine-breakpoint-lg': '75em',
'mantine-breakpoint-xl': '88em',
},
}),
],
};

export default config;

Mantine Imports

Import the Mantine CSS styles in your index.tsx file:

import '@mantine/core/styles.css';

Wrap your application with the MantineProvider component:

import { createTheme, MantineProvider } from '@mantine/core';

const theme = createTheme({
/** Put your mantine theme override here */
});

function Demo() {
return (
<MantineProvider theme={theme}>
<App />
</MantineProvider>
);
}

Simple Example

import { MantineProvider, createTheme } from '@mantine/core';
import '@mantine/core/styles.css';
import { MedplumClient } from '@medplum/core';
import { MedplumProvider } from '@medplum/react';
import '@medplum/react/styles.css';
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { BrowserRouter } from 'react-router';
import { App } from './App';

const medplum = new MedplumClient({
onUnauthenticated: () => (window.location.href = '/'),
});

const theme = createTheme({
headings: {
sizes: {
h1: {
fontSize: '1.125rem',
fontWeight: '500',
lineHeight: '2.0',
},
},
},
fontSizes: {
xs: '0.6875rem',
sm: '0.875rem',
md: '0.875rem',
lg: '1.0rem',
xl: '1.125rem',
},
});

const container = document.getElementById('root') as HTMLDivElement;
const root = createRoot(container);
root.render(
<StrictMode>
<BrowserRouter>
<MedplumProvider medplum={medplum}>
<MantineProvider theme={theme}>
<App />
</MantineProvider>
</MedplumProvider>
</BrowserRouter>
</StrictMode>
);