visit
Last year, Agora — who I work for— announced an exciting rebrand. Our new name is Kojo, and we have a shiny new color palette, crisp typography, spiffy logos, and more. It’s time to say goodbye to our beloved purple and caret logo and say hello to a more modern, yellow and blue future!
❌ Hard coding hex values: <Button backgroundColor="#3C3C43">
❌ Hard coding RGB values: color: rgba(255,255,255,0.5)
❌ Importing a Color
constant to 'darken' or 'lighten' other color values: color: Color(Colors.callout.background).darken(0.35).toString()
❌ Using CSS default colors: borderColor: "red"
❌ Using the Colors
constant: textColor={Colors.tint.primary}
✅ Using the theme
file: <Button backgroundColor={theme.colors.primary}>
Sidebar: How many grays do we even need?
We assumed we would need maybe 3 or 4 grays to use across our app. When working through all of the layers, we realized we needed more. It ended up being NINE different grays across all screens.
How to define colors?
Should we define colors by the color itself, like “blue” or “gray100”? Or should we define the color by the application, such as “mainBackground” and “accent”?
We decided on creating a new palette
constant with all of our new color definitions. Only in this constant could hex codes live. No more RBG, no more custom definitions. This made the code easier to search.
Our palette
looks like this:
const palette = {
black: 'black',
bluePrimary: '#114BBA', // 'Blueprint'
blueSecondary: '#5482DB',
gray1: '#F4F4F3', // 'Slab'
gray2: '#EDEDED',
gray3: '#E7E6E3',
gray4: '#DFDFD8',
gray5: '#ACACA5',
gray6: '#979797',
gray7: '#6C6C6C',
gray8: '#525252',
grayCarbon: '#31302E', // 'Carbon'
green: '#59D06C',
greenMint: '#54DFA5',
notesBackground: '#FFFEE5',
olive: '#797400',
orange: '#FEA000',
pink: '#F44670',
pinkNeon: '#BD3F7C',
red: '#F74541',
tan1: '#E1DDCC', // 'Material'
tan2: '#978B63', // 'Terra'
teal: '#2EC2CC',
white: 'white',
yellowNeon: '#FAFF06', // 'Kojo Yellow'
};
Notice, this palette
is not exported. Then, we updated our theme
file, which contains definitions such as standard text sizes, border widths, etc. This file gets imported into React files. The colors
section of the theme
file looks like:
colors: {
// colors
primary: palette.bluePrimary,
secondary: palette.blueSecondary,
accent: palette.yellowNeon, // grays
contentBackground: palette.white,
appBackground: palette.gray1,
primarySectionBackground: palette.gray2,
primarySectionBackgroundDark: palette.grayCarbon,
headerTop: palette.grayCarbon, stripeBackground: palette.gray2,
divider: palette.gray5,
disabled: palette.gray4, // text
text: palette.black,
textGray: palette.gray7,
textLight: palette.gray6,
textInverted: palette.white, // uniqueColors
preferred: palette.greenMint,
error: palette.red,
success: palette.green, // status colors
pill: palette.gray6,
noIssues: palette.green,
backordered: palette.pinkNeon,
damaged: palette.orange,
missing: palette.red,
wrongItem: palette.teal,
partial: palette.gray6, ...
},
The goal of the theme
file is to be more prescriptive of how to use colors. An engineer doesn’t need to know when to use a gray3
vs a gray4
. But the engineer should know from looking at their mockup from the designer that the text should be gray. So they simply use textGray
.
We added a feature flag for kojoRebrand
that would flip between two palette
variables, the other being named paletteLegacy
for clarity. This change also included changing all of the words Agora
→ Kojo
as well as some emails or links to the updated places.
searching for all "#
values, to see where we were defining custom hex values
searching for all Color(
values, to see where we were darkening or lightening colors
searching for all rgb(
and rgba(
values, to find custom color definitions
We went through every flow of the mobile application with a thorough QA document to make sure the colors and contrast looked good. This can also be tedious, but we found several places with poor contrast or where colors weren’t quite right. We partnered closely with our design team for quick spot checks and advice.
We also added to our Style Guide document for our mobile repository. It contained some best practices for how to define colors, as well as what not to do. Here’s an example:
Engineers will almost always take the easiest path when writing new code — make the easiest path the correct one. In our case, it’s a lot easier to just add color="primary"
than trying to find the hex code of our new primary blue, #114BBA
.
theme
constant.palette
is the only place colors are defined, we could add a paletteDarkMode
that could switch the app to dark mode. 🌚 / 🌞
A version of this article appears .