Setting up Next with Ant Design and React Spring
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!