This video is available to students only

Styling with Ant Design

Throughout Part I of the course, we haven't made any changes to the presentation (i.e. CSS) of our client code. In this lesson, we'll introduce and use the Ant Design React UI framework to improve the appearance of our client application.

📝 This lesson's quiz can be found - here. 🗒️ Solutions for this lesson's quiz can be found - here.

In this lesson, we'll introduce the Ant Design React UI framework and use some of the components from the Ant Design framework to make our client application look more presentable. The objective of this lesson isn't to convey what certain components given to us by Ant Design are but more to convey how we can use a React UI framework to help improve the presentation of what we've built.

First and foremost, we'll install the antd library into our client application.

The antd library is built with TypeScript so we won't have to install any additional type declaration files. When installed, we can begin to use the components that Ant Design provides.

The Ant Design documentation provides a detailed overview of all the different components Ant Design provides as well as the props they accept and examples of their use. In this lesson, we'll simply highlight and use a few certain components.

Ant Design has released a new major version - v4! v4 brings in a lot of out of the box beneficial changes such as upgrading design specifications, introducing a dark theme, making the entire bundle size smaller, etc.

In our course, we've used version v3 throughout. With an upgrade to v4, the vast majority of things we've done in the course remains the same except for a few minor changes that'll need to be made. If you're interested in following along exactly what we've done in our video lessons, do install the latest 3.x.x version of Ant Design (e.g. npm install [email protected]^3.0.0). If you're interested in seeing how v3 can be upgraded to v4, do feel free to refer to Ant Design's V3 to V4 migration guide for more details.

<List>#

The first component we'll use is Ant Design's <List> component. We'll use the <List> component to first render a list of titles from the listings data we retrieve from our GraphQL API.

We'll import the List component module in our Listings.tsx file.

We'll modify the listingsList constant variable we had before to now use Ant Design's <List> component to render a list of elements. As we render the <List> component, we'll use the component's itemLayout, dataSource, and renderItem props.

Our listingsList constant in our <Listings> component will look like the following:

  • The itemLayout prop dictates the layout of how we want each list item to be rendered with which we've given a value of "horizontal".

  • dataSource takes an array or collection of data that'll help prepare the list.

  • The renderItem prop is an example of the render props pattern that dictates how each list item is to be rendered. We're using the child <List.Item> and <List.Item.Meta> components to render the title of each iterated listing.

The <Listings> component handleDeleteListing() method isn't currently being used but we'll use it again shortly.

Though at this moment we'll be rendering the markup from Ant Design, we won't see any CSS that Ant Design gives us. If we take a look at the "use in create-react-app" section of the Ant Design documentation we can that Ant Design expects us to import an accompanying CSS file from the installed antd library.

We'll create an index.css file in a styles/ folder at the root of the src/ folder.

In the index.css file, we'll add the following @import to import the Ant Design stylesheet into our index.css file.

In our src/index.tsx file, we can tell our index.tsx file to use the index.css file by simply importing it.

The ability to simply import our stylesheet in our components can be done thanks to Webpack and the configuration made in create-react-app. This is an incredibly useful feature that allows us to create blocks of stylesheets for respective components. Since index.tsx is the root level "component", applying styles here is applied to all children components as well.

The Ant Design documentation does also show the capability of ejecting the create-react-app configuration and using the Ant Design's babel-plugin-import library to allow for the importing of components with reduced CSS bundle sizes.

In this course, we'll keep things simple and introduce components from Ant Design just like we've done for the <List> component.

Though we're not there yet, when taking a look at our browser - we'll see the markup and styling Ant Design's <List> component gives us!

We'll look to add some custom padding to our list of Listings before we further update the <List> component. We'll create a styles/Listings.css file in the Listings/ folder to act as the stylesheet for the <Listings> component.

In the Listings.css file, we'll introduce a .listings class and give it a margin of 20px as well as a max-width of 750px.

In our <Listings> component, we'll import the newly created Listings.css stylesheet and specify the .listings class in the root <div> element of the component.

If we take a look at our app, we can see the margin and max-width be applied to our list.

We'll now look to populate our list a little more. The <List.Item.Meta> component can take an avatar and description prop. For the description prop, we'll specify a value of the listing address. For the avatar prop, we'll import and use the <Avatar> component that Ant Design provides. We'll import and use the <Avatar> component from antd and provide a src of listing.image. The <Avatar> component also takes a shape and size prop with which we'll provide a shape of "square" and a size of 48.

Our listingsList constant variable will now look like the following:

Just from those changes alone, we'll now have avatars and address descriptions for each of our listing items!

We're still missing the ability to delete a listing. The <List.Item> component can take an actions prop which can be an array of JSX elements that represent the actions that can be taken for a certain list item. We'll introduce this actions prop and attempt to place a single element value. Our element will be the <Button> component from Ant Design.

We'll import the <Button> component and place it as the first item in our array in the actions prop. The <Button> component will have an onClick prop that will have the button trigger the component handleDeleteListing() method when clicked. Ant Design's <Button> component also takes a type prop to control how the button is to appear. To get the primary blue color, we'll apply the value of "primary" to the type prop.

A Delete button will now appear in each list item, and clicking it will allow us to delete the listing from the list!

We won't make any more changes to the <List> component but look to optimize the other parts of our list.

<Spin>#

When we delete a listing, we're still presented with a Deletion in progress... header element at the bottom of our list. We can probably look to use a better loading indicator from Ant Design.

Ant Design offers a component labeled <Spin> that helps display the loading state of a page or a section.

In the Listings.tsx component file, we'll import the Spin component module and wrap the inner contents of our component markup with the <Spin> component. To control when the <Spin> component is visible, we'll set its spinning prop to the value of deleteListingLoading which is the value that represents the loading state of our mutation request. We can also remove the deleteListingLoadingMessage element we've created before.

When deletion is in progress, we'll now be presented with a loading spinner.

<Skeleton>#

When our parent listings query is being made, we have a simple Loading... message be shown. Let's look to display a skeleton UI instead. Ant Design has a <Skeleton> component that can be used in multiple different ways. We'll stick with a simple approach by looking to render a custom component that uses the <Skeleton> element when the query is loading.

We'll keep our new component in a components/ folder within the Listings/ module to represent that it's a child component of <Listings>. We'll create the components/ folder and a ListingsSkeleton/ folder within that will contain a ListingsSkeleton.tsx file and an index.ts file.

Start a new discussion. All notification go to the author.