How we built Linkit for Notion and Adobe XD
We love creating solutions to actually make people's lives a little easier. Developing custom plugins for design tools is one of them. Get your favorite code editor out and type along as Teun tells how our latest plugin for Adobe XD came about.
This blog post was originally published on the Adobe Tech Blog
Here at Yummygum we love using Adobe XD. We can quickly prototype, wireframe, build and leverage a component library. We also religiously use Notion. It’s an extremely handy and versatile workspace and note-taking tool, making our day-to-day activities and project management a breeze. How neat would it be if we could somehow combine these two tools; fill a Notion database with real data, and have it sync up with our designs?
We solved this problem by creating Linkit, a plugin for Adobe XD. With Linkit you can easily synchronize your Notion databases to your Adobe XD designs. We also worked on the Confetti plugin in the past.
How does it work
The solution we’ve made is as nifty as it is straightforward. Linkit acts as a bridge between Adobe XD and Notion database(s). Once you’ve added Linkit as an integration in Notion you can start binding database columns to your design. Linkit matches names of Adobe XD file’s layers with the content in your Notion database allowing full content synchronization. When you’ve made changes in Notion, you simply use the “Re-Sync with Notion” button from the Linkit plugin in Adobe XD. All the data that’s linked in Adobe XD will update.
The interface of the plugin is simple to use. But under the hood a lot is going on. And that’s exactly what drives us at Yummygum, putting in the work to make things super usable. Let’s get a bit more technical and let’s take a look at how it works.
UXP lets plugin developers use several different types of interfaces. For Linkit, we’ve used a combination of a Panel and Modals as the user interface. Have a look at the extensive Adobe XD Plugin lifecycle documentation to learn more about the different kinds of interfaces you can use for your plugin.
Panels are positioned in the left sidebar of Adobe XD. They extend all the way up and down, and can be resized horizontally. We use a Panel for Linkit to house the primary interface of the plugin.
Linkit’s Panel, positioned in the right sidebar of Adobe XD.
Now having a Panel is nice, but how can we create one programmatically? The engineers at Adobe have created something super helpful for all plugin developers out there. Using UXP’s PanelController constructor we can define our custom Panel. It accepts two parameters: The first a custom (React) component, in this case <App /> , and a second object parameter containing configuration for the panel. Besides the panel id you can specify any menu items which will appear in the plugin’s menu here as well.
Besides Panels, you can create Modals with UXP. Modals are customizable popup windows that contain some application logic. For Linkit we use several different Modals to guide the user through the installation and configuration process. The Modal can interact with any of the UXP APIs, like storing a token in LocalStorage.
One of Linkit’s modals, prompting the user for their Notion token.
Creating a Modal works similarly to how you would create a Panel. You use the CommandController constructor to which you pass along a component and some additional configurations. Like the title of the window and the window size. To open a Modal you simply call the .run() property on the controller.
Creating a UXP plugin
Inside panels and modals you can put any HTML or React components, but it’s recommended to make as much use of Spectrum UXP components as possible. Spectrum is Adobe’s design system, providing a unified set of components that are styled similarly across all of Adobe’s apps. Using a Spectrum UXP component in a UXP plugin is pretty easy. There are no libraries or stylesheets to include. Just use them as you would any other HTML tag.
<sp-button variant="primary">I'm a Spectrum button</sp-button>
Combine the Spectrum components with some application logic, and you’ll quickly have a plugin developed. Now let’s take a look at how to step up your plugin’s functionality even further by connecting to an external API. We’ll use Linkit as an example by showing you how it connects to the Notion API.
Connecting to an external API
One of the reasons we love Adobe XD so much is because it ships with so many incredible features. For Linkit we felt like one of the few possible ways to make Adobe XD even more valuable to us was by pulling in the strengths of an external tool/data source. Connecting to an external API is a great way to add more functionality to your plugin. This will work a little bit differently depending on which kind of API you’re connecting to, but the general steps are the same. You initialize the client and then use it to perform API calls. Luckily for Linkit, Notion has a simple and easy to use client for the Notion API.
We’ve set up the client in the Linkit codebase in a separate file. To initialize the client and make calls to the Notion API we only need a token. The user inputs the token from Notion in the Linkit plugin interface we described earlier. The modal uses the setNotionToken() method to set the token.
We can then make API calls to Notion from different components by calling the method(s) exposed on the notion client object.
Making use of API data in Adobe XD
Every API will interact with data and manage that same data in different ways. For most codebases this means you’ll need to develop some sort of transformation method which will format the data to something usable by a second piece of software. In the case of Linkit this meant that we needed to transform the text style data retrieved from Notion into something that the Adobe XD UXP API understands.
Converting text styling to Adobe XD
Say you want to use an external API as a source to make styled text in Adobe XD. The way this works using UXP is:
Create or query a Text object (layer)
Set the Text property of the object to the desired string
Use properties like styleRanges, underline, and strikethrough to apply text styles to (parts) of the text.
Here’s an example.
Pretty easy right? Now how the same kind of data is represented outside Adobe XD will probably be different for the API you use. It’s quite likely that we can’t just blindly obtain data from the API and apply it to the Adobe XD element expecting it to work. In our case we had to add a small conversion step. Notion mostly uses boolean values for all of the different styling properties. Here’s an example column from the Notion API.
As you can see the Description object contains an array value rich_text which has objects containing annotations on how parts of the text should be styled. To convert this into something that looks the same in Adobe XD we wrote a custom method. The method takes an array of Notion rich_text objects, and converts it to properties that can be set on an Adobe XD element.
We can now use this method anywhere in our application to render stylized text from Notion in Adobe XD!
If you’re familiar with web development, creating a UXP plugin is fun, easy and straight-forward. UXP is highly suitable and the API is very well equipped to create any type of plugin you want. The only thing that is required is your own imagination to make it happen.
Has this sparked your interest in developing a plugin for Adobe UXP? It’s really easy to get started. You can follow the quick start guide on the Adobe UXP developer docs.
We’d love to see what you think of our Linkit plugin. But we’re even more curious to see what plugins you’ll be creating yourself! Don’t forget to give us a nudge if you’re ready to share your results. Because we’re loving all those Adobe XD plugins!