DEV Community

Vinodh Kumar
Vinodh Kumar

Posted on • Updated on

Create a react app using Vite - Part 2

Styling

I'm going with TailwindCSS as my default styling utility library. Skip this if you have other preferences.

Tailwindcss

  • Install the TailwindCSS and initialize it using the below commands.
  pnpm add -D tailwindcss postcss autoprefixer
  npx tailwindcss init
  touch postcss.config.js
Enter fullscreen mode Exit fullscreen mode
  • The init command will create a tailwind.config.js file in the root directory where we can configure the tailwind library. Update the config file content property to process the HTML, and TS files in src and public directory as follows.
export default {
  content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
  theme: { extend: {} },
  plugins: [],
}
Enter fullscreen mode Exit fullscreen mode
  • Now we should let the postcss preprocessor know that we are using tailwindcss in our project. To do that, open the postcss.config.js file and add the 'tailwindcss' option to the plugins list.
export default {
  plugins: { tailwindcss: {}, autoprefixer: {} },
}
Enter fullscreen mode Exit fullscreen mode
  • Open /src/index.css file and update it with the following content
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
Enter fullscreen mode Exit fullscreen mode
  • Open the src/App.tsx file and update the h1 tag as follows and check whether the tailwind class is applied successfully.
<h1 className="text-green-500">Vite + React</h1>
Enter fullscreen mode Exit fullscreen mode

Rendering icons

SVGs are the best image format for rendering icons for the following reasons.

  • They are small in size
  • The same icon can be used in different places in different sizes without losing the quality, that's why it's called Scalable Vector Graphics.
  • A monochromatic icon can be rendered in different colors just by applying CSS

To render the icons inline I'm using this SVGR plugin to transform the SVGs to react components and then import it wherever necessary just like importing a normal react component.

  • Install the necessary packages
 pnpm add -D @svgr/core @svgr/plugin-svgo vite-plugin-svgr
Enter fullscreen mode Exit fullscreen mode
  • Update the Vite config to automatically convert the SVGs into react components.
export default defineConfig({
  ...,
  plugins: [
    ...,
    svgr({
      svgrOptions: {
        plugins: ['@svgr/plugin-svgo', '@svgr/plugin-jsx'],
        svgoConfig: {
          plugins: ['preset-default'],
        },
      },
     }),
  ]
});
Enter fullscreen mode Exit fullscreen mode
  • Update the package.json file
  ...,
  "scripts": {
    ...,
    "format:svg": "prettier --write '**/*.svg' --parser 'html'",
    "format": "prettier --write . && pnpm format:svg",
  },
  "lint-staged": {
    "**/*.{js,ts,tsx}": [
      "eslint --fix"
    ],
    "**/*.svg": "prettier --write --ignore-unknown --parser 'html'",
    "**/*": "prettier --write --ignore-unknown"
  },
  ...
Enter fullscreen mode Exit fullscreen mode
  • Open src/vite-env.d.ts and add the following entry to avoid the ReactComponent SVG error while importing.
/// <reference types="vite-plugin-svgr/client" />
Enter fullscreen mode Exit fullscreen mode
  • Let's make use of the already available react.svg and see how we can import it as an inline SVG. Update the /src/app.tsx as follows,
import { ReactComponent as ReactIcon } from 'src/assets/react.svg'

export const App = () => {
  return (
    <div className="font-semibold text-lg text-green-500">
      <ReactIcon width="24px" height="24px" className="text-blue-500" />
      Rendered from react app
    </div>
  )
}
Enter fullscreen mode Exit fullscreen mode

Things to remember

We need to make sure we import SVGs the right way so they are highly customizable and scalable. Rendering the SVGs as inline, allows us to customize the SVG properties such as dimensions, fill color, and stroke color through props.

For the library to properly parse the SVG and allow us to customize it inside our components ensure the following.

  1. The SVG you are adding has the fill property in the SVG as 'currentcolor' so it's easy to customize this color based on the prop. Please see reference SVG src/assets/react.svg.
  2. The SVG shouldn't have width and height set so we can set them inside our components when used. (They will be overwritten anyways but it's better to avoid width and height in the SVG being added)
  3. Try to open the SVG in the browser and start deleting the unwanted elements present in the SVG by inspecting the elements in the developer console and making sure only valid tags are present and checking for any visual changes. If there are no visual changes we can delete those elements from the SVG.
  4. Set the path element's fill property to inherit so that the color will be inherited from the SVG element itself.
  5. Check the SVG size after making these changes.
  • If the size of SVG is < 1kb then it's eligible to render as an inline icon. Put the SVG in the src/assets/icons path and render it inline using the component.
  • If the size > 1kb then it will increase the bundle size and affect the performance. Put the SVG in the src/assets/images folder and render it using <img> tag src. This way it will not hinder the page load.
  • This 1kb is an arbitrary value, but it is advised to have a threshold beyond which the icons should be rendered using image tags only.

PS: You can also create a generic UI component wrapper that accepts the SVG as input and render it with some default sizes and config.

Next part

In the next part of this series, we will see how to add unit testing support to our app using JEST.

Top comments (0)