Skip to main content
Version: v2.0

Custom Themes for Flatfile Portal

Theming gives you independent control over the look and feel of Flatfile Portal. With this, you can adjust both a global styles and individual components within the importer, as well as control the CSS pseudo-class :hover on buttons.

How it works

Portal Theming is one of the optional settings within the FlatfileImporter Options. For simplicity's sake, the below code example shows only the global setting, and then we will expand out a bit more on each specific area and what can be customized.

import FlatfileImporter from "@flatfile/adapter";

const importer = new FlatfileImporter("license_key", {
type: "Theming Demo Imports",
fields: [
{ key: "name", label: "Name" },
{ key: "email", label: "Email" },
],
theme: {
global: {
backgroundColor: "#212327",
textColor: "#c2c3c3",
primaryTextColor: "#c2c3c3",
secondaryTextColor: "#c2c3c3",
successColor: "#c2c3c3",
warningColor: "#c2c3c3",
fontFamily: "font",
},
// other keys below
},
});

As mentioned above, the theme key is an options key within the Portal Options. This key is an object with keys that reference specific areas of the importer. Below you will see each key and how to work with it in more depth.

global

The global key is a generic and easy-to-use key for giving a very general/global styling or even some defaults to then override in more specific keys. Some of these keys work very similarly to Portal Theme's predecessor, styleOverrides . So if you previously used that, some of these will look familiar. The options available in the global key are:

  • backgroundColor - This will control the general background color of the importer. Note that this does not control the main manual input and review tables during the process, but those can now be controlled as well.
  • textColor - This sets a default text color for the importer. Much like with the backgroundColor setting, this does not apply to the manual input and review tables, but that too can be controlled in another setting below.
  • primaryTextColor - This will get slightly more specific than the previous textColor key.
  • secondaryTextColor - This too is a more specific styling that the textColor key.
  • successColor - This controls some specific UI elements like certain buttons, icons and some text.
  • warningColor - Like successColor, this controls some specific UI elements like certain buttons, icons and some text.
  • fontFamily - This allows for you to set the custom font within the theme. Please note that you must also import the fonts in the integrations setting

buttons

The buttons key allows for control of the buttons within the importer. This key also allows for the use of the :hover pseudo-class for styling buttons in a deeper manner. All buttons have the ability to use backgroundColor , color , padding , border , fontSize , borderRadius and ":hover" . With these options in mind, there are a few different button options for styling as follows:

  • primary - Controls the primary buttons within the importer.
  • secondary - Controls the secondary buttons within the importer.
  • tertiary - Controls the tertiary buttons within the importer.
  • success - Controls the success, confirm match, etc buttons that by default end up green.
  • headerMatchYes - Controls the 'Yes' button in the header matching screen.
  • headerMatchNo - Controls the 'No' button in the header matching screen.

As an example for these, and to keep the code cleaner and DRYer, the theme will reference the following button styling objects.

const primaryButton = {
backgroundColor: "#00c6ff",
color: "#002d3d",
border: "1px solid #00c6ff",
padding: "6px 16px",
fontSize: "15px",
borderRadius: "8px",
":hover": {
backgroundColor: "#0D93BA",
border: "1px solid #0D93BA",
},
};

const secondaryButton = {
backgroundColor: "transparent",
color: "#00c6ff",
border: "1px solid #00c6ff",
padding: "6px 16px",
fontSize: "15px",
borderRadius: "8px",
":hover": {
backgroundColor: "#00c6ff",
border: "1px solid #00c6ff",
color: "#002d3d",
},
};

const tertiaryButton = {
backgroundColor: "#DE781F",
color: "#002d3d",
border: "1px solid #002d3d",
padding: "6px 16px",
fontSize: "15px",
borderRadius: "8px",
":hover": {
backgroundColor: "transparent",
border: "1px solid #DE781F",
color: "#DE781F",
},
};

And here's what this might look like when being used.

    theme: {
buttons: {
primary: primaryButton,
secondary: secondaryButton,
tertiary: tertiaryButton,
success: primaryButton,
headerMatchYes: {
...primaryButton,
padding: "6px 40px"
},
headerMatchNo: {
...secondaryButton,
padding: "6px 40px"
}
}
}
note

The remainder of the keys below will all use a root option. This option will control the base styling of the area of the specific section. This will allow for control of backgroundColor, border, borderRadius and padding while the more specific options within each key will control fontWeight , fontSize and color."

progressBar

The progressBar allows for the styling of the progress indicator section (sometimes called breadcrumbs) in the top right that indicates which stage of the import process you have completed, are currently on and are still to come. Here are the options for this key:

  • root - Controls the base stylings for the section.
  • current - Controls the styling of the current step.
  • complete - Controls the styling of the completed steps.
  • incomplete - Controls the styling of the incomplete steps.
    theme: {
progressBar: {
root: {
backgroundColor: "grey",
borderRadius: "4px",
border: "1px solid white",
padding: "20px"
},
current: {
color: "blue",
fontSize: "24px",
fontWeight: "600"
},
complete: {
color: "green"
},
incomplete: {
color: "yellow"
}
}
}

This key controls the styling for anything above the tables in the importer outside of specific items like the above progressBar or dropzone pieces which have their own styling. Here are the available options for use:

  • root - Controls the base stylings for the section.
  • title - Controls the header title text in the upper left. This text will by default say "Bulk add" and whatever you set your import type to or will match the value provided in the title configuration option.
  • closeButton - Controls the styling of the button to close the importer in the top right corner. This styling will allow for the same use of the ":hover" option in the buttons key above.
    theme: {
header: {
root: {
backgroundColor: "#171a1d"
},
title: {
color: "white"
},
closeButton: {
color: "white",
":hover": {
color: "yellow"
}
}
}
}

This key controls the root stylings of the bottom of the importer. The only option available to use here is the root key.

  • root - Controls the base stylings for the section.
theme: {
footer: {
root: {
backgroundColor: "#171a1d";
}
}
}

dropzone

This key allows for the control of the dropzone section that appears when the importer first opens. Note that the button inside this section is controlled by the buttons for the importer and not in this section. Here are the available options:

  • root - Controls the base stylings for the section.
  • content - Controls the bubble that defaults with dotted lines. This section will use the same styling options as root but will control a different section of the dropzone.
  • fileTypes - Controls the styling for the content on the right paragraph.
  • accepted - Conrtols the styling for the content on the left paragraph.
    theme: {
dropzone: {
root: {
backgroundColor: "#171a1d"
},
content: {
backgroundColor: "#171a1d",
border: "none",
borderRadius: "20px",
padding: "40px 60px"
},
fileTypes: {
border: "none",
color: "yellow"
},
accepted: {
color: "yellow"
}
}
}

manualInput

This key will control the styling for the manual input table that appears when the importer is initially loaded. Keep in mind that if diasbleManualInput: true is in your settings, this key is unneccesary as this table will never display. Here are the available options:

  • root - Controls the base stylings for the section.
  • title - Controls the base stylings and the text styling for the section right above the actual manual input table. By default, this section will say "...or just manually enter your data here:"
  • table - Controls the table elements with additional nested options for table specific elements such as th , td , etc.
    theme: {
manualInput: {
root: {
padding: "20px"
},
title: {
margin: "0",
padding: "16px 30px",
backgroundColor: "#4c5057",
borderRadius: "20px 20px 0 0",
fontSize: "14px",
fontWeight: "400"
},
table: {
th: {
backgroundColor: "#2c3135",
color: "#6a7c87",
borderColor: "#2c3135"
},
td: {
color: "black"
}
}
}
}

headerMatch

This controls styling on the header matching phase of the import process. Here are the available keys:

  • root - Controls the base stylings for the section.
  • content - Controls the text content of everything on the left side of this stage and anything not inside a table element.
  • icon - Controls the arrow icon fill color. Its only available option is the fill key.
  • table - Controls the tables within this stage. It uses a very similar format to the above manual input table where its nested options are that of table elements such as th , td , etc.
    theme: {
headerMatch: {
root: {
backgroundColor: "#171a1d"
},
content: {
fontSize: "14px"
},
icon: {
fill: "yellow"
},
table: {
th: {
backgroundColor: "#212327",
color: "#6a7c87",
borderColor: "#212327"
},
td: {
color: "black"
}
}
}
}

columnMatch

This key controls the elements in the column matching/mapping stage of the importer.

  • root - Controls the base stylings for the entire section.
  • content - Controls the text color within the data preview part of the table (left side) and the background/base/root of each field's card.
  • rule - Controls the text color of the right side of each card.
  • autoMatchRule - This is a nested object that is associated only with field content on the right that informs the user a field has been matched. You can use root , field , description and icon to control different aspect of the line that will tell you that the data in the card has been match to a certain field.
    theme: {
columnMatch: {
root: {
backgroundColor: "orange"
},
content: {
backgroundColor: "white",
color: "blue"
},
rule: {
color: "red"
},
autoMatchRule: {
root: {
backgroundColor: "grey"
},
field: {
color: "purple"
},
description: {
color: "green"
},
icon: {
fill: "pink"
}
}
}
}

dialog

This key controls the styling of the dialog boxes that will pop up for confirmations and input from users during the import flow. The keys available for use are:

  • root - Controls the base stylings for the section.
  • content - Controls the styling of content in the top part of the dialogs.
  • footer - Controls the styling of the content on the bottom of the dialogs.
  • overlayColor - Controls the color for the overlay around the dialogs.
    theme: {
dialog: {
root: {
backgroundColor: "#2c3135",
borderRadius: "20px",
border: "none"
},
content: {
fontSize: "16px",
fontWeight: "500",
border: "none",
padding: "30px 30px 15px"
},
footer: {
backgroundColor: "orange",
border: "none",
padding: "15px 30px 30px"
},
overlayColor: "rgba(34,139,34,0.5)"
}
}

dataSource

When giving a datasource other than a csv file (xls for example) there is a dialogue that will go through the individual sheets and has its own flow. This key controls the styling for that dialogue. Here are the available options:

  • root - Controls the base stylings for the section.
  • title - Controls the styling for the title of the dialog.
  • subtitle - Controls the styling for the subtitle for the dialogue (for xls this will say "select sheet").
  • step - Controls the styling for the steps/progress indicators for the dialog.
  • footer - Controls the footer section of the dialog.
    theme: {
dataSource: {
root: {
color: "yellow"
},
title: {
fontSize: "17px",
textAlign: "left"
},
subtitle: {
fontSize: "15px",
textAlign: "left",
fontWeight: "400"
},
step: {
margin: "0",
padding: "0 0 0 16px"
},
footer: {
color: "yellow"
}
},
}

loader

When the importer is initially loading, there is a loading indicator that will appear. This key styles that indicator and its container.

  • root - Controls the base stylings for the section.
  • overlayColor - Controls the color of the overlay that surrounds the dialog container.
    theme: {
loader: {
root: {
backgroundColor: "#1B3D46",
color: "#c2c3c3"
},
overlayColor: "rgba(0,0,0,0.5)"
},
}

iterator

  • root - Controls the base stylings for the section.
  • overlayColor - Controls the color of the overlay that surrounds the iterator.
    theme: {
iterator: {
root: {
backgroundColor: "#1B3D46",
color: "#c2c3c3"
},
overlayColor: "rgba(0,0,0,0.5)"
}
}

Here is a full snippet of all of the pieces from above.

    theme: {
global: {
backgroundColor: "#212327",
textColor: "#c2c3c3",
primaryTextColor: "#c2c3c3",
secondaryTextColor: "#c2c3c3",
successColor: "#c2c3c3",
warningColor: "#c2c3c3",
fontFamily: "font"
},
buttons: {
primary: primaryButton,
secondary: secondaryButton,
tertiary: tertiaryButton,
success: primaryButton,
headerMatchYes: {
...primaryButton,
padding: "6px 40px"
},
headerMatchNo: {
...secondaryButton,
padding: "6px 40px"
}
},
progressBar: {
root: {
backgroundColor: "grey",
borderRadius: "4px",
border: "1px solid white",
padding: "20px"
},
current: {
color: "blue",
fontSize: "24px",
fontWeight: "600"
},
complete: {
color: "green"
},
incomplete: {
color: "yellow"
}
},
header: {
root: {
backgroundColor: "#171a1d"
},
title: {
color: "white"
},
closeButton: {
color: "white",
":hover": {
color: "yellow"
}
}
},
footer: {
root: {
backgroundColor: "#171a1d"
}
},
dropzone: {
root: {
backgroundColor: "#171a1d"
},
content: {
backgroundColor: "#171a1d",
border: "none",
borderRadius: "20px",
padding: "40px 60px"
},
fileTypes: {
border: "none",
color: "yellow"
},
accepted: {
color: "yellow"
}
},
manualInput: {
root: {
padding: "20px"
},
title: {
margin: "0",
padding: "16px 30px",
backgroundColor: "#4c5057",
borderRadius: "20px 20px 0 0",
fontSize: "14px",
fontWeight: "400"
},
table: {
th: {
backgroundColor: "#2c3135",
color: "#6a7c87",
borderColor: "#2c3135"
},
td: {
color: "black"
}
}
},
headerMatch: {
root: {
backgroundColor: "#171a1d"
},
content: {
fontSize: "14px"
},
icon: {
fill: "yellow"
},
table: {
th: {
backgroundColor: "#212327",
color: "#6a7c87",
borderColor: "#212327"
},
td: {
color: "black"
}
}
},
columnMatch: {
root: {
backgroundColor: "orange"
},
content: {
backgroundColor: "white",
color: "blue"
},
rule: {
color: "red"
},
autoMatchRule: {
root: {
backgroundColor: "grey"
},
field: {
color: "purple"
},
description: {
color: "green"
},
icon: {
fill: "pink"
}
}
},
dialog: {
root: {
backgroundColor: "#2c3135",
borderRadius: "20px",
border: "none"
},
content: {
fontSize: "16px",
fontWeight: "500",
border: "none",
padding: "30px 30px 15px"
},
footer: {
backgroundColor: "orange",
border: "none",
padding: "15px 30px 30px"
},
overlayColor: "rgba(34,139,34,0.5)"
},
dataSource: {
root: {
color: "yellow"
},
title: {
fontSize: "17px",
textAlign: "left"
},
subtitle: {
fontSize: "15px",
textAlign: "left",
fontWeight: "400"
},
step: {
margin: "0",
padding: "0 0 0 16px"
},
footer: {
color: "yellow"
}
},
loader: {
root: {
backgroundColor: "#1B3D46",
color: "#c2c3c3"
},
overlayColor: "rgba(0,0,0,0.5)"
},
iterator: {
root: {
backgroundColor: "#1B3D46",
color: "#c2c3c3"
},
overlayColor: "rgba(0,0,0,0.5)"
}
}

Should I remove my styleOverrides if I plan to start using Portal Theming?

We recommend that if you want to use this newer Portal Theme that you should remove the styleOverrides setting all together. While it technically won't hurt anything if you leave them in, if you use both settings, anything in styleOverrides will be ignored/disabled. This means that even if you aren't technically overriding some of the same pieces of the importer, the default styles would be in place over what you have in the styleOverrides setting.