UI Library Integration
This page provides guidance on working with common external libraries to build Custom Pages in Vault.
Styled Components
Section link for Styled ComponentsUse StyleSheetManager
The following code uses styled-components
import { definePage } from '@veeva/vault';
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import { StyleSheetManager } from 'styled-components'
export default definePage(({ element }) => {
const stylesRoot = document.createElement('div');
const reactRoot = document.createElement('div');
element.appendChild(stylesRoot);
element.appendChild(reactRoot);
const root = createRoot(reactRoot);
root.render(
<StyleSheetManager target={stylesRoot}>
<App />
</StyleSheetManager>
);
})Emotion-Based Libraries
Section link for Emotion-Based LibrariesEmotion-based libraries such as Material UI
The following example defines a Custom Page using Material UI and configures the Emotion cache for style injection:
import { definePage } from '@veeva/vault';
import React from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import createCache from '@emotion/cache';
import { CacheProvider } from '@emotion/react';
export default definePage(({ element }) => {
const myCache = createCache({
key: 'material-ui-emotion-cache',
container: element
});
const root = createRoot(element);
root.render(
<CacheProvider value={myCache}>
<App />
</CacheProvider>
);
})HTML Attributes for Styling
Section link for HTML Attributes for StylingSome libraries that use Emotion for styling rely on attributes set on the <html> tag to render styles correctly. However, when UI code is placed within the shadow DOM, it isn't wrapped in an <html> tag. This can lead to visual and CSS issues due to the absence of necessary attributes.
To address these issues, we recommend wrapping your UI code in a <div> or a similar container and applying the necessary attributes to ensure proper styling. For example, Chakra UI
<div data-theme="light" style={{ 'color-scheme': 'light' }}>
<App />
</div>You should add these attributes to a container element that encapsulates the entire UI. Different attributes might be necessary when using other UI libraries.