We’re introducing Merge - UXPin's enterprise feature.
Let's look at how easy it is to integrate a React-based library into Merge to design with code on a day-to-day basis. All that without designers learning how to code!
UXPin Merge lets designers import developer’s existing custom React components in a seamless fashion to create interactive prototypes using real code, which is unlike anything else traditional design tools offer.
This eliminates the need for designers to manually maintain a “second” design system within their design tool and instead provides the entire team with a single source of truth. The result? The disconnect between designers and developers is gone when building digital products.
We want to save you time so we’ve designed this tutorial to integrate Mozilla’s React Todo App example with Merge. After the integration, you’ll be able to use the app’s components to design an interactive Todo list prototype within UXPin!
Remember to start by requesting access to Merge – you can do it here. After the verification process and the setup, you’ll be ready to design with code! Also, don’t worry about integrating with GitHub – we don’t have any requirement of where the codebase should be located, so you can use whatever you want!
The Todo app has three React components:
These components are in the `src/components` directory and are outlined in the screenshot below:
When this tutorial is completed, a designer will be able to create a prototype with these components. Your real-world custom design system (DS) likely has many more than three components. However, the concepts we’ll illustrate in this tutorial should apply to your DS as well.
To begin, fork then clones the following link https://github.com/mdn/todo-react. Then install our UXPin Merge NodeJS package, which includes our CLI.
A custom design system requires two additional config files:
UXPin typically doesn’t need to use your entire existing Webpack build process. We’ll use a more minimal and default build for UXPin. Create a uxpin.webpack.config.js file and paste the following code into it:
const path = require("path");
const webpack = require("webpack");
module.exports = {
output: {
path: path.resolve(__dirname, "build"),
filename: "bundle.js",
publicPath: "/"
},
resolve: {
modules: [__dirname, "node_modules"],
extensions: ["*", ".js", ".jsx"]
},
devtool: "source-map",
module: {
rules: [
{
test: /\.(s*)css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
]
},
{
loader: "babel-loader",
test: /\.js?$/,
exclude: /node_modules/,
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
}
},
]
}
}
For components you want to use in UXPin merge, you must specify their file directory in the uxpin.config.js file at the top of the directory of the repo. As you can see in the code snippet below, we’ve only added the ‘Form’ component src/components/Form.js for now and will add the other components later in the tutorial.
Create a uxpin.config.js and paste the following content into the file:
module.exports = {
components: {
categories: [
{
name: 'General',
include: [
'src/components/Form.js',
]
}
],
webpackConfig: 'uxpin.webpack.config.js',
},
name: 'Learn UXPin Merge - React Todo list tutorial'
};
Lastly, Babel-loader will be used by Webpack to create the app bundle. To install babel use the following commands: yarn add babel-loader –dev then yarn install .
CONGRATULATIONS👏 You’re all good to go and have the minimum configuration required to view the Form component.
Experimental Mode lets us prototype with our local components to verify their behavior before pushing to UXPin. Now, to open UXPin Merge Experimental mode to preview the Form component, run ./node_modules/@uxpin/merge-cli/bin/uxpin-merge –disable-tunneling. In Experimental Mode, using –disable–tunneling makes requests go directly to your localhost web server. Quick note: UXPin with –disable-tunneling option works only in Chrome .
Using the settings provided in `uxpin.webpack.config.js`, Experimental mode bundles your components and opens a browser window. You can lay out components in a similar fashion as the UXPin Editor. After Experimental Mode loads, drag and drop the Form component from the sidebar onto the project canvas:
Just like your custom design system, this Todo app contains global styles. These are specified in the `src/index.css` file. All of our components need the styles specified in this file. We can load this file via a Global Wrapper Component. This component will wrap around every component we drag onto the UXPin canvas.
Create a wrapper file:
mkdir src/wrapper/
touch src/wrapper/uxpinwrapper.js
Copy and paste the following into `UXPinWrapper.js`:
import React from "react";
import '../index.css';
export default function UXPinWrapper({ children }) {
return children;
}
The `import ‘../index.css’;` line ensures our CSS styles are loaded prior to rendering each component.
We need to tell UXPin to use this wrapper file. Add the following to uxpin.config.js:
wrapper: 'src/wrapper/UXPinWrapper.js',
In your terminal, restart UXPin Experimental mode using ./node_modules/@uxpin/merge-cli/bin/uxpin-merge –disable-tunneling. A restart is required when updating the config file. A browser reload is only required when updating components.
Experimental mode should open a new browser window with a styled Form component:
Now we’ll work on adding the FilterButton to UXPin Merge. These buttons are displayed below the Form component:
Adding this component will be similar to the Form component. However, I’d also like to give designers the ability to specify the text that is displayed within the button. We’ll do that via the `prop-types` package.
Component propTypes are mapped to the UXPin properties panel when editing a component. The existing FilterButton component doesn’t use prop-types so let’s add this to `FilterButton.js`:
import React from "react";
+ import PropTypes from 'prop-types';
function FilterButton(props) {
return (
@@ -15,4 +16,9 @@ function FilterButton(props) {
);
}
+ FilterButton.propTypes = {
+ name: PropTypes.string
+ }
+FilterButton.defaultProps = {
+ name: 'Button Name'
+};
export default FilterButton;
Add `’src/components/FilterButton.js’` to `uxpin.config.js` and restart using ./node_modules/@uxpin/merge-cli/bin/uxpin-merge –disable-tunneling. A restart is required as we’ve updated the config file. When Experimental Mode starts, you should see a new “FilterButton” component listed in the sidebar. Click and drag this onto the canvas.
Two of our three components are now working with UXPin Merge. We have one component remaining: the Todo component.
We’re moving on to our final component: the Todo. These are displayed within the list of todo items in the UI:
When adding the FilterButton, we edited the FilterButton.js file to add propTypes. What if you want to isolate your Merge-specific changes and don’t want to modify the source code of your components? We can create a wrapper that is specific to the Todo component for this. It’s similar in concept to the Global wrapper component we used to apply CSS styles but will be specific to the Todo component.
Type the following:
mkdir -p src/components/merge/todo
touch src/components/merge/todo/Todo.js
Copy and paste the following code into Todo.js.
import React from 'react';
import PropTypes from 'prop-types';
// Import the original component
import TodoM from '../../Todo';
function Todo(props) {
return <TodoM {...props}/>
}
Todo.propTypes = {
/**
* If `true`, the todo will be marked as completed.
*/
completed: PropTypes.bool,
/**
* The name of the todo.
*/
name: PropTypes.string,
toggleTaskCompleted: PropTypes.func,
}
Todo.defaultProps = {
name: 'Do Laundry'
};
export default Todo;
We’re importing the original Todo component as `TodoM` and returning this component in our newly defined `Todo` function. We specify propTypes just like we did with the FilterButton component on our newly defined `Todo` wrapper function.
Add ‘src/components/merge/todo/Todo.js’ to uxpin.config.js and restart using ./node_modules/@uxpin/merge-cli/bin/uxpin-merge –disable-tunneling. After Experimental launches a new window, click-and-drag the Todo component onto the canvas:
You’ll see the Todo component along with the default “Do Laundry” todo name. This default name is only applied when using Merge.
Until you push your design system to UXPin the components are only visible to you. To let your design team use these components we need to push the component bundle to UXPin. Creating and pushing a Merge design library requires two steps:
1. Create the library within the UXPin UI
a. Go to your UXPin account
b. Enter the UXPin Editor
c. Create a new library
d. Select the option import React components
e. Copy the Auth token (don’t share it with anyone and do not place it in any files checked into git repository. This token provides direct access to the library on your account.) The process looks like this:
2. Push the library via the uxpin-merge CLI
Using the token created from the previous stop, run the following from within the project repo:
./node_modules/@uxpin/merge-cli/bin/uxpin-merge push –token YOUR TOKEN
Your design team can now access the Merge library.
Now that the Merge design library has been pushed its time to test it out within the UXPin editor:
You should have a solid looking prototype:
How does a designer hand off a prototype back to a developer?
Now that we’ve built a quick prototype in UXPin we’re ready to export it back to our app. We can preview the output and then use Spec mode to copy and paste the JSX code for our components.
Click the play button in the upper right corner of the editor. Once the preview loads click the “Spec” link at the top. You can now click on the components and view the JSX code to generate them in the right panel:
It’s great to push an initial version of our design system. However, you’ll likely need to push out quite a few updates over time.
The FilterButton has a “pressed” state to indicate the currently active filter. Looking at the live React app, here’s the difference between the pressed and not-pressed state:
Let’s add support for this state. Make the following change to `src/components/FilterButton.js`:
FilterButton.propTypes = {
- name: PropTypes.string
+ name: PropTypes.string,
+ isPressed: PropTypes.bool
}
Commit the change to git and push to UXPin:
git add.
git commit -m “Added isPressed prop to button”
./node_modules/@uxpin/merge-cli/bin/uxpin-merge push –token YOUR TOKEN
Merge components are automatically synced to the most recently pushed code. To show the latest, reload the tab showing the UXPin editor. Select a FilterButton. In the right panel of the editor you should see a new “isPressed” property. Select it to activate this state:
Follow this same flow (git commit + uxpin-push) when you make future changes. Prototypes will automatically use the latest pushed version of components.
You’ve taken a React app and pushed its components to UXPin Merge. You’ve also learned how to push updates when you modify components or add new ones. Now your design team can use these components to create high-fidelity prototypes within the UXPin editor.
You can browse the source code for this project on GitHub. To learn more advanced Merge techniques see our Merge docs or reach out to us at [email protected].
Don’t have UXPin Merge yet? First, remember to go through the process of requesting access to make the most of designing with code!
Previously published at https://www.uxpin.com/studio/blog/design-with-code-tutorial/