Setting up Next with Ant Design and React Spring

Aleksandar Rajic
6 min readMay 19, 2019

Hello fellow devs! For some time, i am eager to try Next as well as Ant Design so in the next couple of articles i will be developing fancy portfolio website. The goal of this article is to put us on the right track and setup development environment for creating any rich user interface using Next framework in combination with Ant Design framework and React Spring animation library. Here I won’t focus on other interesting and necessary things, like state management, communication with APIs, deployment, etc. That will be subject for some other time. :)

So let get started!

First create application directory called portfolio, navigate to it and initialize npm.

mkdir portfolio
cd portfolio
npm init -y

Now we can start adding packages to it.

Next

Next is the React framework that comes with a lot of options ready out-of-the-box, so it makes initial setup as simple as just installing it, along with react and react-dom.

npm install react react-dom next

Now you just need to add scripts to your package.json

{
...
"scripts": {
"dev": "next",
"build" "next build",
"start": "next start",
},
...
}

Start development by running

npm run dev

Thats it! You are ready to start. Application is running at localhost:3000.

This is bare minimum of what you need to start developing applications. However, the power of Next is that it is highly customizable, so we will be making slight modifications to our configuration in the following parts of this article.

Details about Next and its features can be found at official docs page.

Ant Design

Ant Design is minimalistic React UI framework that gives us a lot of components and guidelines how to build modern and rich interfaces. It comes with predefined theme but allows us to customize it fairly easy in order to meet our needs. For styling components Ant Design uses less and a set of variables for each set of design aspect, which which we will be modifying. List of all variables can be found here. So let start by adding all necessary packages.

npm install antd less @zeit/next-less babel-plugin-import

The main package for Ant design is antd. For less support we need to install less and @zeit/next-less packages. The last plugin is needed in order to import ant design into Next application. We will be needing couple of files so create .babelrc in your root directory and configure it to user next/babel presets and import antd package.

{
"presets": [
"next/babel",
],
"plugins": [
[
"import",
{
"libraryName": "antd",
"style": false
}
]
]
}

We also need to create next.config.js file in our root directory and configure webpack to work with less

const withLess = require('@zeit/next-less');module.exports = withLess({
webpack(config) {
config.module.rules.forEach((rule) => {
if (rule.use && Array.isArray(rule.use)
&& rule.use[0] === 'extracted-loader') {
const lessLoader = rule.use[rule.use.length - 1];
if (lessLoader.loader === 'less-loader') {
lessLoader.options = {
javascriptEnabled: true,
compress: true,
};
} else {
console.error('less-loader patch failed')
}
};
});
return config;
}
});

Define theme file in assets/theme and for example call it ant-theme.less. In there override all necessary variables to customize our theme. For start, change primary color.

@primary-color: #ffb713;

Finally, create style.less file in the root directory in order to import ant styling and your own theme file.

@import './node_modules/antd/dist/antd.less';
@import './assets/theme/ant-theme.less';

That is it. Now let check everything looks nice. Create pages/index.js and paste following code.

import {
Button,
Typography,
} from 'antd';
const { Title } = Typography;export default () => (
<div
style={{ padding: 20 }}
>
<Title>Welcome!</Title>
<Button
type="primary"
onClick={() => alert('Greetings!!!')}
>
Greet
</Button>
</div>
);

You should see something like this

You can notice that button has primary color which is defined in assets/theme/ant-theme.less with variable @primary-color to value #ffb713.

React spring

React spring library represents a mix of animated and react-motion libraries with interpolation and performances of animated and ease of user of react-motion. It offers 5 hook, useSpring, userSprings, useTrail, useTransition and useChain, which allow you to create powerful animations. For the purpose of this setup, we will use the simplest one, useSpring. Later on we will be using more complex animations.

All you need to do in order to start animating is to install this library.

npm install react-spring

Now we will be animating our Greet button. We will be using example from official docs, with slightly modified values.

In order for animations to work on custom component we need to use animated HOC which will enable it on any component we create wether it is React or React Native components. React spring comes with predefined animated html tags we can use, for ex. animated.div, animated.button, etc.

First thing to do is to create animatedButton component in library directory. Note: we will be putting all elementary components inside library directory, while any other component goes to components directory.

import { Button } from 'antd';
import { animated } from 'react-spring';
const AnimatedButton = animated(Button);export default AnimatedButton;

We define animate variable using useState hook, which will toggle animation and x property using useSpring hook, which goes from 0 to 1 in one second.

const [animate, toggle] = useState(false);
const props = useSpring({
from: { x: 0 },
x: animate ? 1 : 0,
config: { duration: 1000 },
});

Now we define steps in animation using keyframes.

range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1]
output: [1, 1.97, 1.9, 2.1, 1.9, 2.1, 1.03, 1]

Each value in range array has its output value, which represents state of the component in that key frame. we pass these two arrays to interpolate function in the style property of component. Here we use transform to animate but in general any css property is valid option. Then, we chain another interpolate function which will scale component.

<Button
type="primary"
onClick={() => toggle(!animate)}}
style={{
transform: props.x
.interpolate({
range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
output: [1, 1.97, 1.9, 2.1, 1.9, 2.1, 1.03, 1]
})
.interpolate(x => `scale(${x})`)
}}
>

Animation is triggered on button click and the end result should be something like this.

Final code.

import { useState } from 'react';
import { Typography } from 'antd';
import { useSpring } from 'react-spring';
import Button from '../library/Button';
const { Title } = Typography;export default () => {
const [animate, toggle] = useState(false);
const props = useSpring({
from: { x: 0 },
x: animate ? 1 : 0,
config: { duration: 1000 },
});
return (
<div
style={{ padding: 20 }}
>
<Title>Welcome!</Title>
<Button
type="primary"
onClick={() => toggle(!animate)}
style={{
transform: props.x
.interpolate({
range: [0, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 1],
output: [1, 1.97, 1.9, 2.1, 1.9, 2.1, 1.03, 1]
})
.interpolate(x => `scale(${x})`)
}}
>
Greet
</Button>
</div>
)
};

Now you have all elementary blocks for building interesting presentations.

If you are into more complex interfaces feel free to extend this setup with all necessary libraries, or stay tuned for future post on state management and side effects. ;)

Let me know your thoughts in the comments bellow.

Have fun!

--

--

Aleksandar Rajic

Tech Lead at Manigo & Writter at Software Engineering Crafted