Introducing design tokens, new colour foundations and dark mode

Hi @danielwester. Our current solution for Connect apps and Forge Custom UI adds the current theme and mode as data attributes to <html> inside the iframe. This is done automatically and will sync to reflect the same theme as the host (Jira/Confluence). Under the hood it’s using the setGlobalTheme API documented here.

Hi @lkimmel. Were you experiencing this on a *.jira-dev.com instance or *.atlassian.net? There shouldn’t have been any data-theme attributes present yet :thinking:

I experience that on my instance Log in with Atlassian account
The attribute is missing for issue panels, and jira admin pages, which had that attribute until last week. We developed against them to be prepared :smiley: .
But not for global pages, which still have the data-theme attribute.

If I understand you correctly, this means that you are going to inject code into the HTML of the iframe? Given that this is not your HTML to control, that means you are adding it to the HTML element from the all.js include? Or will it be done on iframe onLoad event handler?

So we need to wait for that to load and manipulate the DOM before the data- attribute is set. Also, how will you handle iframe that do not have <html /> root elements? Or will you just use the root element?

To be honest, I think manipulating iframe document is a bad practice and I’m not sure why you would choose this over adding it to the query string or providing an AP method?

3 Likes

To add to @remie 's questions - how will you handle redirects? Also - how will it be done in custom ui? Can we get some sample code to demonstrate how you expect a react app to behave? (Since we do have custom components that will have to adapt as well).

2 Likes

@stephenmok any chance of getting a pre-release/beta version of the new Atlassian Figma Design Tokens Plugin?

@remie

If I understand you correctly, this means that you are going to inject code into the HTML of the iframe? Given that this is not your HTML to control, that means you are adding it to the HTML element from the all.js include? Or will it be done on iframe onLoad event handler?

Currently, all.js will perform all of the orchestration, so apps will not need to configure anything to get theming working. That does mean that we will inject attributes onto the element as well as inject style sheets into the .

These are necessary to be able to trigger CSS selectors (activate a theme) and allow apps to read and respond to the theme state accordingly. For example, if you have brand-specific colours that need to be changed between light/dark modes.

So we need to wait for that to load and manipulate the DOM before the data- attribute is set

I’m not sure if I understand this point, but you shouldn’t need to manipulate the DOM relative to the timing of the data attr. What are the other scenarios where you need to manipulate the DOM? If you can share examples we’ll look into it.

how will you handle iframe that do not have

We have not come across this use case yet, what kind of scenarios would an app not have a element?


@danielwester

how will it be done in custom ui? Can we get some sample code to demonstrate how you expect a react app to behave? (Since we do have custom components that will have to adapt as well).

Both Connect & Forge Custom UI will take a similar approach, they both handle the theme configuration behind the scenes when the app loads. So similar to the above, you’ll see stylesheets containing theme files mounted to the page and attributes attached to the HTML element.

Usage in both Connect & Forge Custom UI will follow the same pattern shown in our docs: https://atlassian.design/components/tokens/examples#button

how will you handle redirects?

Redirects are not a scenario we’ve come across yet in our early explorations. Could you share some context on this for us to look into?


@BrianOffenheim

@stephenmok any chance of getting a pre-release/beta version of the new Atlassian Figma Design Tokens Plugin?

Yeah, we’re planning to share that very soon, within the next month :slight_smile: We’ll update this thread when we have more information.

What I meant is that the app needs to wait for all.js to load and manipulate the DOM to set the data theme attribute. Which is latency, especially for server-side rendered apps. If you pass the theme in the query string, we can construct the HTML with the correct data attribute ourselves.

In general, I really really really really want to stress that you should not ever make DOM manipulation to iframe content. Apart from the latency that you are introducing, manipulating iframe document content is a bad practice. This is not your code to manipulate.

Making pro-active changes to DOM elements is not the same as using all.js to provide utility Javascript functions, or applying changes based on options attributes we put on script tags.

I cannot stress this enough. If I don’t want to apply theming to my apps, I should be able to do this without having to be concerned about Atlassian injecting code into MY document and altering behaviour of components.

If you move forward with this, we will have to reconsider using AtlasKit as I do not condone Atlassian to take this crucial design responsibility away from us.

6 Likes

The point is that you should not even have to consider this use case. That is the whole premise of an iframe. It is not your code. If I want to use XML+XSLT, which is a completely valid way of creating an iframe document, I should be able to do so.

You are making assumptions about code that is outside of your control. Don’t do that.

5 Likes

@DanielDelCore - I’m with Remie on this, and couldn’t have said it better.

You are injecting content into my app, where I “own” the design.
This is not your app to mess with. It is not your decision to change how my app renders. That is entirely on me.

How do you envision this to work if we’ve made customizations to Atlaskit components that we use? And if you’re manipulating the DOM in my page, am I supposed to now keep track of the changes you made? What happens if I decide to re-render the screen, or do other crazy things that wipe out your DOM manipulations?

It also seems, you did not contemplate how this is supposed to work with apps that use server side rendering. If our app uses server side rendering, this now means that the page gets rendered, then all.js loads and does its thing, and then theming is supposed to kick in after that. To me, this sounds like there is a scenario where the server renders the page in light mode, will potentially get rendered in light mode first, and then has to switch over to Dark mode, because we don’t know from the server side that Dark mode is desired.

6 Likes

Consider this simple example scenario: My very popular and useful app needs to display the image of a beautiful celestial body as a background. In light mode it should show the sun, in dark mode it should show a black hole. The app needs to do a REST call to find an appropriate image. When do I do that? Also, I need to render matching UI in the iframe on the server side. What will be displayed in the iframe before the theme is set? What if my iframe opens a server-rendered SVG document instead of HTML?

4 Likes

I’ll also second Remie and Ademoss here about injecting stuff in the app. Atlassian is so very careful to make their components black boxes, to the point where when I asked for a className property on the simplest UI component in Atlaskit a while ago I was told that it’s impossible to do because it would violate encapsulation and break maintainability and the sky would fall. But when it comes to just manipulating the internal contents of app-generated documents, without any idea what they contain and do, that’s OK. You don’t even see the potential issues there after being told of them repeatedly.

3 Likes

Uhm… I think there are a lot of apps out there that either redirect to another end point or just loads a whole new page in the iframe. all.js handles that so your approach would handle that.

That said. Can you talk about how you expect non atlaskit interactions? Will you document the data attributes that you’re setting as 100% expected behavior so that we can rely on it? Will the all.js block until that is set? Will there be a dom event triggered?

4 Likes

@DanielDelCore Thank you for the further information.
After checking the documentation, I have not seen any documentation how to handle design tokens in server rendered apps.
For some parts of our app we use atlassian-connect-express (ACE) with the default handlebars templates on the server side. This defaults currently to AUI. How can we use design tokens in this scenario?

2 Likes

Exactly. Don’t make assumptions about what apps might or might not need to do. This is a very basic principle that absolutely needs to be respected when making architectural decisions. Otherwise, this will cause a lot of frustration both for vendors and for their app users.

An API / dev framework is supposed to allow its consumers to do things you don’t even think about now.

Unfortunately, Atlaskit has and has had so many issues that I switched to my own component library. It would be more helpful to have a theming API that does not rely on bundled atlaskit libraries.

From my perspective a +1 to the AP.context or URL method, as @bbutnaru said - preferably not asynchronous to avoid flashing

1 Like

@DanielDelCore is there a reason why the Design System Team is not going for a more unopinionated approach and allow the consumer to decide how to implement theming?

Why not just have all three scenario’s?

  1. Have all.js apply theme data-theme attribute if enabled via data-options on the <script /> tag or #ac-iframe-options div (as documented here https://developer.atlassian.com/cloud/jira/platform/about-the-connect-javascript-api/#options)

  2. Pass the theme as a query string to the iframe URL

  3. Add the theme to the result of AP.context.getContext()

12 Likes

@DanielDelCore is there any provision for the app to programmatically select a the theme (i.e., override the global setting), both for the whole app iframe or for a sub-tree of the document? I can’t find anything like that in the docs.

I found it. The extension used to be mirrored in this repo. The linked files might be out-of-date. To make it run: Check out the repo. Switch to the directory. Remove prettier references from package.json (Atlassian prettier config is in a private repo). Install babel-loader@8 directly into this directory. Run “npm run build-chrome-extension”. Then load …/dist/tokens-browser-extension/ as Chrome extension in developer mode.

Result:

@Atlassian: Why do we have to do this kind of Reverse Engineering? Can you please share the up-to-date version of this Chrome extension?

3 Likes

Hey all, lots to unpack here, I’ll try my best to address everything but forgive me if anything is missed.

Firstly, just a reminder that we are very early in the integration process. The details we’ve shared above are for the MVP, but we fully expect your feedback to help shape the end product, this is why we created this post. We’re still learning and open to making changes so please continue sharing your feedback. From what I’ve read so far, these are all fair concerns and I’ll make sure they’re captured. I’m keen to work with you folks to understand more, so feel free to share specifics here or we can reach out via email if you’re interested.

If I don’t want to apply theming to my apps, I should be able to do this without having to be concerned about Atlassian injecting code into MY document and altering behaviour of components.

Is there a reason why the Design System Team is not going for a more unopinionated approach and allow the consumer to decide how to implement theming?

@remie @danielwester, this is totally understandable, with the current automatic orchestration it would activate tokens in Atlaskit components even if your app is not ready or willing to be themed. I can see how that would be a problem. The original intent of this was to make it so there was very minimal configuration overhead necessary to use tokens. But I think, given these points, we should revisit that.

How would you feel about having one or more AP methods trigger & listen to it instead, even if it does modify attributes on the HTML element?

It is not your decision to change how my app renders. That is entirely on me.

I agree with this, similar to the point above, we can make it a deliberate opt-in.

Will you document the data attributes that you’re setting as 100% expected behaviour so that we can rely on it?

@danielwester The changes we do make to the page will be limited to HTML data attributes and style tag insertions, but will not change the way your custom UI renders if it is not also using our design tokens. We’ll try to keep this as passive as possible. And yes, these will be well-documented and dependable behaviours.

If our app uses server-side rendering, this now means that the page gets rendered, then all.js loads and does its thing, and then theming is supposed to kick in after that.

We’ve not tackled SSR yet, we need to make some changes to factor it in, but I would expect this to work with some additional configuration. I’m going to talk to a few folks internally this week to see how we can approach it and get back to you.

Can we get the secret atlassian theme chrome extension for app development?

Why do we have to do this kind of Reverse Engineering? Can you please share the up-to-date version of this Chrome extension?

Great find @julianwolf & @lkimmel, the chrome extension is something we are planning to share with everyone as a theming development tool, it allows global theme switching from anywhere in the App.

At this time we have not publically shared the extension, but we plan to do so once theming is opened up to the ecosystem and is ready for developers to begin migrating their apps.

Thanks again for jumping into this post, the team and I will continue to monitor the comments here and try our best to answer to the best of our ability.

Cheers!

3 Likes