Theming
UI components in the Gusto Embedded React SDK ship with simple baseline styles that are fully themable. "Themable" means that components are designed to take on the look and feel of the application in which they are embedded.
For a complete inventory of available variables, see theme variables.
Theming is the recommended approach for customizing your UI. For advanced customization, however, where theming is insufficient to completely match your application UI, you can explore usage of component adapters which allow you to completely supply your own components.
Setting up styles
Before configuring theming, you must import the SDK styles:
import '@gusto/embedded-react-sdk/style.css'
Developers typically apply this import at the application root where they are also setting up the GustoProvider.
The SDK's root class and overlay portal
The imported styles scope everything to a GSDK class. The SDK renders one GSDK-classed element in place, wherever you mount GustoProvider, and a UI component like Select, ComboBox, DatePicker, Menu, or MultiSelectComboBox renders its dropdown/popover content into a separate GSDK-classed element that the SDK appends directly to document.body — not into the in-place one. This keeps overlay positioning correct regardless of position, transform, filter, or contain on any element between your GustoProvider mount point and document.body.
Because both elements carry the plain GSDK class, a global rule you write against .GSDK applies to both. If you need to target only the visible, in-place content and leave the (invisible, until a dropdown opens) portal root alone, exclude it with .GSDK:not(.GSDK-portal-root):
/* Applies only to the SDK's in-place root, not the overlay portal */
.GSDK:not(.GSDK-portal-root) {
max-width: 800px;
}
If you render GustoProvider inside a shadow root, pass an explicit portalContainer (an element inside your shadow root) to GustoProvider. document.body sits outside every shadow boundary, so without an explicit container, overlay content would render outside your shadow root's style encapsulation.
<GustoProvider
portalContainer={myShadowRootElement}
theme={{/* ... */}}
config={{ baseUrl: `/proxy-url/` }}
>
{children}
</GustoProvider>
Theme variables
A theme is a collection of variables that determine how the SDK UI components will look. There are theme variables available for colors, typography, shadows, and more. The React SDK ships with a basic default theme as a starting point, but it is expected that developers will override theme variables to make the React SDK fit seamlessly into their application.
See theme variables for a complete list of available variables.
Setting a Theme
You can set your theme by passing variables to the theme prop of the GustoProvider component.
import { GustoProvider } from '@gusto/embedded-react-sdk'
import '@gusto/embedded-react-sdk/style.css'
function MyApp({ children }) {
return (
<GustoProvider
theme={{
colorPrimary: 'red',
colorPrimaryAccent: 'darkred',
colorPrimaryContent: 'white',
fontFamily: 'Courier New',
}}
config={{
baseUrl: `/proxy-url/`,
}}
>
{children}
</GustoProvider>
)
}
Accessibility
Having sufficient color contrast is important to ensure your UI is accessible to all users. To meet color contrast requirements, you must ensure sufficient contrast between each background color and its corresponding content color.
For example, consider the body color variables:
colorBody
colorBodyAccent
colorBodyContent
colorBodySubContent
The colorBodyContent and colorBodySubContent colors will be displayed on top of both colorBody and colorBodyAccent backgrounds. You must ensure sufficient color contrast between:
colorBodyandcolorBodyContent/colorBodySubContentcolorBodyAccentandcolorBodyContent/colorBodySubContent
The same principle applies to primary colors (colorPrimary/colorPrimaryAccent and colorPrimaryContent). All color variables follow this naming pattern, and the same contrast requirements apply to each color group.