I have an exciting idea for an application tailored for the Atlassian Marketplace. Picture this: your team is in the middle of sprint planning, tasked with estimating a new feature in story points. But there's a problem - team members can't reach a consensus. Some are convinced of one estimate, while others argue for a different number, leading to a stalemate. What can be done to resolve this deadlock?
Enter a new kind of solution: an application that invites the entire team to sing a motivating song together. After that, the energy shifts, and the team is not only more motivated but also better aligned, enabling quicker and more efficient decision-making.
The app must look great in both light and dark themes. After all, many developers swear by the dark mode, and without this option, they might not be as enthusiastic about participating. Ensuring a visually appealing interface in both themes is critical for the app's success.
This new application will be developed for Jira Cloud, leveraging the power of the Forge framework to create a seamless and engaging experience.
We're not going to dive into the step-by-step process of building an app from scratch here - we've got plenty of guides for that (One App to Rule Them All: Conquer Jira Cloud with All Atlassian Forge Modules in a Single App! , Essential Guide to Atlassian Forge Modules for Jira ). For now, let's say we've used the Forge Issue Panel module to display our app’s content, paired with React for a Custom UI. Fast-forward through the setup, and voilà, our first version of the app is up and running! (Picture it: light theme on the left, dark theme on the right).
It’s clearly amazing... but let’s be honest, it’s not quite looking like a Jira-native masterpiece just yet. Here’s what we need to fix:
Fonts, spacing, and basic styles: These need to match Jira’s default look, so our app feels like a natural extension of the platform.
Background and colors: They need to adapt seamlessly to whatever theme the user has - whether they’re a fan of the sunny light mode or living in the dark side with the dark theme.
Controls: Right now, it’s just a button, but even that should look and feel like it belongs in Jira.
A quick and easy win? Just one simple import from the css-reset (check it out here: https://atlassian.design/components/css-reset/examples) and boom - your padding, margins, and fonts are instantly aligned with Jira’s look.
import '@atlaskit/css-reset';
And voilà! The result is looking a bit better. The font now matches Jira's, which is great... but sadly, the colors and background? Still off. Baby steps, right?
So, after bravely conquering this massive guide (https://developer.atlassian.com/platform/forge/design-tokens-and-theming/), we’re ready to make two key updates to our app:
1. Wrap all our code in the index.tsx
file with the magic snippet below.
// index.tsx
import { view } from '@forge/bridge';
import ReactDOM from 'react-dom/client';
import { App } from './app/App';
import '@atlaskit/css-reset';
void view.theme.enable().then(() => { const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement); root.render( , ); });
2. Replace all those hard-coded color names with sleek “tokens” like this example.
// App.tsx
import { token } from '@atlaskit/tokens';
export const App = () => {
return (
<div>
<button>Next song</button>
<div style={{ color: token('color.text'), whiteSpace: 'pre-line', }} >
... the rest part of the App ...
And guess what? The result looks way better - whether you’re rocking Light or Dark mode, the fonts, colors, and spacing are all on point now.
Time for a few more tweaks - let’s upgrade our buttons and any other controls with some proper UI components. Trying to manually match Jira’s CSS styles? That’s a wild goose chase. Instead, we can use the same UI framework that Jira uses for its own elements: (https://atlaskit.atlassian.com/). It’s got everything you need for the UI - buttons, labels, inputs, tables, you name it.
// App.tsx
import Button from '@atlaskit/button/new';
import { Box } from '@atlaskit/primitives';
import { token } from '@atlaskit/tokens';
export const App = () => {
return (
<Box>
<Button>Next song</Button>
<Box style={{ color: token('color.text'), whiteSpace: 'pre-line', }} >
... the rest part of the App ...
The result? Our buttons (and everything else) will look just like they do in Jira. Success, right?
Wait, does this mean we’ve finally achieved a fully native-looking app in both light and dark themes? Can we start selling it on the Marketplace?! Well, almost… except for one small thing. There’s still that pesky issue with “raised” views, like when an Issue View pops up in a modal window (you know, when you click on an issue from the List view).
To tackle that last little issue, we’ll create a styles.css
file with the following magic:
/* styles.css */
html, body, #root {
background-color: transparent; /* fix for raised views */
}
Then, just import it into your index.tsx
like this:
// index.tsx
import './styles.css';
And behold the beauty! Raised views now blend in perfectly. It’s like the finishing touch on a masterpiece.
Achieving flawless light and dark theme support for your Custom UI is easy - ust follow these four simple steps:
Use @atlaskit/css-reset
to reset all the styles in your app to the Jira “default.”
Enable theme switching and use design tokens for all colors and spacing. No hard-coded colors allowed!
Stick to Atlaskit components as much as possible - they look seamless and come with built-in theme support. Plus, they just make life easier.
Set the default background color to transparent to handle those “raised” views like a pro (background-color: transparent;
).
I was totally going to share the source code, but then I realized it’s so amazing that I have no choice but to sell it on the Atlassian Marketplace - as soon as they introduce the ‘Amazing Apps for Motivation’ category. Stay tuned!
Andrei Pisklenov _Actonic_
Head of Development
Actonic
Germany
3 accepted answers
0 comments