Color and Typography Updates in v9
Everything you need to know about the latest style updates in Base Web
The Base design system has undergone a small makeover. baseui
v9 updates the component library to meet these latest specs. This includes black as the new primary color, a more accessible color palette, and an update to the typography sizing ramp.
Migration Guide
After bumping to v9, your app will probably look a little different. Don't panic! If you address each of the points below your app will look right in no time!
- Customize your theme if the color changes in v9 are not to your liking. Read more 📖
- Update usage of typography theme values (
font100
for example) to the new scale. Read more 📖 - Update usage of typography components (
Paragraph1
,H1
) to the new scale. Read more 📖
Be sure to check out our codemod for automatically migrating your codebase to v9! Or, read on for more detail on all of the changes included in this new major.
Black is the New Blue
We have changed the primary
color in our default light theme from blue to black. Blue still lives on in our components as the new accent
color but has a greatly reduced role. Also, note that the dark theme now uses white as the default color for primary
.
These changes are most noticeable in our buttons and the highlights on various inputs (controls). So what should you do if you aren't ready for full on black & white?
Default Branding
If you use our default colors and you want to use blue as the primary
color still, you can simply set primary
back to blue in your theme primitives
object.
// myTheme.jsimport {createTheme, lightThemePrimitives} from 'baseui/themes';import {colors} from 'baseui/tokens';const myThemePrimitives = {...lightThemePrimitives,primary: colors.blue400,primary50: colors.blue50,primary100: colors.blue100,primary200: colors.blue200,primary300: colors.blue300,primary400: colors.blue400,primary500: colors.blue500,primary600: colors.blue600,primary700: colors.blue700,};const myTheme = createTheme(myThemePrimitives);export default myTheme;
Custom branding
If you use custom colors in your theme, v9 will change how your colors are applied to components. In a few cases primary
has been replaced by the new accent
color so you will want to assign accent
to something from your brand in your theme primitives
object. If you do not need the additional theme variable, the easiest thing to do will be to set accent
to the same color as primary
.
// myTheme.jsimport {createTheme} from 'baseui/themes';const myTokens = {// define various brand colors here...colors: {neonPink400: '#FF69B4',},};const myThemePrimitives = {// define all the various primitives for my theme...// adding in custom "accent" primitivesaccent: myTokens.colors.neonPink400,accent50: myTokens.colors.neonPink50,accent100: myTokens.colors.neonPink100,accent200: myTokens.colors.neonPink200,accent300: myTokens.colors.neonPink300,accent400: myTokens.colors.neonPink400,accent500: myTokens.colors.neonPink500,accent600: myTokens.colors.neonPink600,accent700: myTokens.colors.neonPink700,};const myTheme = createTheme(myThemePrimitives);export default myTheme;
For more on how our theme system works, including how to override default theme values, check out this page.
In summary, use the primitives
object to assign semantic meaning to your project's colors. If you need more fine grained control over how colors are used you may need to do some reassignments within createTheme
's overrides
parameter.
Using overrides
// myTheme.jsimport {createTheme} from 'baseui/themes';const myTokens = {// define various brand colors here...};const myThemePrimitives = {// define all the various primitives for my theme...};const myThemeOverrides = {// override baseui default theme assignments...colors: {borderFocus: myThemePrimitives.accent,},};const myTheme = createTheme(myThemePrimitives, myThemeOverrides);export default myTheme;
The following sections detail theme variables you can override to adjust the look of your app after bumping to v9.
Button Group
The ButtonGroup
component has been updated to use buttons with kind={KIND.secondary}
rather than the previous tertiary
. If you still want to use tertiary
you can now use kind
as a top-level prop on ButtonGroup
:
<ButtonGroup kind={KIND.tertiary} />
This will set the children buttons to whatever kind you have passed to ButtonGroup
. You can then theme these various button group kind
s with a set of new theme variables:
buttonPrimarySelectedTextbuttonPrimarySelectedFillbuttonSecondarySelectedText // default selected kindbuttonSecondarySelectedFill // default selected kindbuttonTertiarySelectedTextbuttonTertiarySelectedFillbuttonMinimalSelectedTextbuttonMinimalSelectedFill
A note on the minimal
Button
We are deprecating the minimal
button. tertiary
now serves the same purpose and so the two are redundant. We haven't removed the option yet to avoid an additional breaking change, so you can still set your buttons to kind={KIND.minimal}
and use theme variables to target them. We encourage you to use tertiary
going forward instead, however, as the minimal
button may be removed in a future major.
Datepicker
The Datepicker
component has a new set of theme variables that allow for much more fine-grained customization. Previously it was a little difficult to theme the Datepicker
and generally required overrides
. Note that the old datepicker theme variables are deprecated- they remain in the theme object for backward compatibility.
calendarBackgroundcalendarForegroundcalendarForegroundDisabledcalendarHeaderBackgroundcalendarHeaderForegroundcalendarHeaderBackgroundActivecalendarHeaderForegroundDisabledcalendarDayBackgroundPseudoSelectedcalendarDayForegroundPseudoSelectedcalendarDayBackgroundPseudoSelectedHighlightedcalendarDayForegroundPseudoSelectedHighlightedcalendarDayBackgroundSelectedcalendarDayForegroundSelectedcalendarDayBackgroundSelectedHighlightedcalendarDayForegroundSelectedHighlighted
Links
The primary
color values used for Link
in light and dark themes have been updated to suit the new black/white aesthetic. You may want to update these theme variables to suit your own primary colors.
linkTextlinkVisitedlinkHoverlinkActive
Progress Steps
Updating the ProgressSteps
component to black required some new theme variables. Feel free to use them for your own customizations:
progressStepsCompletedTextprogressStepsCompletedFillprogressStepsActiveTextprogressStepsActiveFillprogressStepsIconActiveFill
Tag and Toast and Notification Kinds
The Tag
, Toast
, and Notification
components have been updated to account for the move to black. Here is what you need to know:
The Tag
component supports a new value, accent
, for the kind
prop, which is blue by default. You can use the following set of new theme variables to customize it:
tagAccentSolidBackgroundtagAccentSolidHovertagAccentSolidActivetagAccentSolidDisabledtagAccentSolidFonttagAccentSolidFontHovertagAccentLightBackgroundtagAccentLightHovertagAccentLightActivetagAccentLightDisabledtagAccentLightFonttagAccentLightFontHovertagAccentOutlinedBackgroundtagAccentOutlinedHovertagAccentOutlinedActivetagAccentOutlinedDisabledtagAccentOutlinedFonttagAccentOutlinedFontHovertagAccentFontDisabled
The Toast
and Notification
components also have a kind
prop, which is info
by default. The style for info
can now be set with a few new theme variables:
toastInfoBackgroundnotificationInfoBackgroundnotificationInfoText // used for Toast and Notification text 🤔
Breakpoints
Unrelated to color but related to theming: we have updated the default breakpoints in the theme object. The largest breakpoint is now 1136px
. You can set it back to 1280px
in your theme.
const theme = {breakpoints: {large: 1280,},};
Base Color Palette
The base color primitives for both the default light and dark theme have been adjusted. These have been changed to improve the contrast ratios across our color palette.
New Black
Blue Changes
Red Changes
Green Changes
Orange Changes
The changes in most of the colors are quite subtle, but the gray (mono) palette has shifted more noticeably. Here are the updated grayscale values:
Gray Changes for Light Theme
Gray Changes for Dark Theme
Color Tokens
You can access any of Base Web's colors on the colors
object exported by baseui/tokens
. You can read more this new module here.
import {colors} from 'baseui/tokens';const theme = {primary: colors.blue400,};
Typography
We have updated the typography scale included in our theme. This is the biggest breaking change in v9. We have removed values from the scale and shifted the default values upwards, so for instance, font200
is now 14px
rather than 12px
. We have updated all of the components in the library to use lower typography values such that component sizing is unchanged. However, references to typography values in your code will likely need updating.
A number of values have been removed from the typography scale. If you reference any of these in your code, you must update these references! Here are the removed values:
font460
font470
font500
font600
font700
font800
font900
font1000
font1100
Typography Mapping
All of Base Web's components have been updated to adjust to the new scale such that there is very little visual change (with regards to sizing) in the components themselves. Still, you may have built some of your components or made adjustments using the typography theme object. References in your codebase will need to be updated accordingly.
Here is the mapping of v8 to v9 typography values that we used in updating our components:
Here is an example of updating direct uses of font theme variables in source code:
// old// font300 used to return 14px/20px/400const StyledFoo = styled('div', props => ({...props.$theme.typography.font300,}));// new// font200 now returns 14px/20px/400const StyledFoo = styled('div', props => ({...props.$theme.typography.font200,}));
If you use the Block
component to apply theme font properties, you will need to adjust those as well:
// old<Block font="font300" />// new<Block font="font200" />
Note, all of this can be done automatically with our new codemod.
Comparison to v8
The following is a comparison of the old and new typographic values:
You can see from this table that the new scale is not entirely equivalent to the old one. The new scale "resets" at font1150
for Display
sizes rather than growing linearly with each step. This means when migrating to v9 you have some choices to make with regards to how you map typography variables.
Typography Components
All of the baseui/typography
components have been updated according to the new typography ramps. Each typography theme value now maps one-to-one with a typography component.
There are a few important changes to note:
- There are now four levels each of Display, Paragraph, and Label (up from one, two, and two respectively).
Paragraph
andLabel
no longer increase infont-size
as the digit suffix increases. This has been changed so that all of the typography components decrease in size as the suffix increases, to stay consistent with the header (h1
) pattern in HTML. This means you will want to changeLabel1
andParagraph1
toLabel3
andParagraph3
. This can be done automatically with our new codemod.Caption1
andCaption2
have been deprecated in favor ofParagraph4
andLabel4
respectively. TheCaption
components have not been removed but instead aliasParagraph
andLabel
components. A future major may see these components removed, so it is best to swap your use ofCaption
forParagraph
andLabel
. This can be done automatically with our new codemod.
For reference, here is a mapping of v8 to v9 components:
Body
These values are used for body text: Label
, and Paragraph
.
Header
These values are used for various headers: H1
, H2
, etc.
Display
These values are used for special headers, usually in association with marketing material. Internally, we assign these properties to a different font-family
. This gives your app a little visual variety.
Codemod
We made a codemod to help projects migrating to v9. You can run it with a single command via npx
:
$ npx @uber-web-ui/baseui-codemods --mod=v9Styles --dir=<path_to_code>
This will go through all of the *.js
files in your codebase, updating any usage of theme font values or typography components to their v9 counterparts, following the various mappings in this post.
The codemod does not update your theme or colors. You should use theme variables and overrides if you want to customize the colors of various components.
Run the script, check your diff, and click through your app to make sure things look good.
Note, the codemod may not work perfectly- if we forgot any edge cases we will update the script (one more reason to use npx
). Click here for more information on baseui
codemods.
Inspiration
Some folks may wonder why there is a noticeable stylistic update coming to Base Web. Aren't most components already implemented?
It is important to remember that the Base design system is still evolving. The Base Web library has an ever-moving target ahead of it. Style changes are, at this point, a constant reality for the project.
We consider this to be one of the main features of Base Web. Folks who use the Base design system know that by staying on the latest version of baseui
, their app remains on-brand and consistent with other products.
That said, we know these sorts of changes can be disruptive. We don't anticipate stylistic changes of this magnitude to come very often. When they do we will try to make the transition as painless as possible with migration guides (such as this blog post), codemods, and backward compatible mappings wherever possible.
Thanks for using baseui
!