npm package: @rahuls360/ui-library
Description: A test project to build a reusable component library published on npm registry. Built using [TDSX](https://tsdx.io/).
Author: Rahul Makhija
Latest version: 0.1.2

# React based Component Library

A test project to build a reusable component library published on npm registry. Built using [TDSX](https://tsdx.io/).

## Features

- Thing components
- Button component


## Setup guide

- Install dependencies using `yarn install`
- Run server in watch mode using `yarn start`
- Run server in production mode using `yarn build`
- Check if tests are passing using `yarn test`
- To work in development mode, use `yarn storybook`


## Publish package to NPM

- Login to npm using `npm login`. This step sets up your .npmrc globally.
- Test your project using the `example` folder. 
- Ensure you've updated the version in package.json file. If you forget, the command will fail anyways.
- npm publish is free for public packages
- Run `npm publish`

## Example folder

- Uses a zero config bundler called parcel to test the published npm package
- It mimics a consumer application.
- Use `npm install` to install the dependencies
- `index.html` contains an empty DOM node & imports our `example/index.tsx` file
- `example/index.tsx` loads polyfills for older browsers. Contains our code that uses our components from the `/dist` folder.
- Consists of `npm start` and `npm run build` commands
- This setup isn't suitable for development mode


### Notes

- tsdx uses rollup internally. We can override it using `tsdx.config.js`
- `.storybook/main.js` contains the storybook config. Modified it to allow .stories.[ext] file anywhere inside `src` folder
- `src/index.tsx` contains all components (Things, Button, etc), as they need to be used as `import { Button } from '@rahuls360/package';`
- Storybook exports a meta config.
  - Uses a title (name of component), component, argTypes
  - argTypes allow a user to modify attributes in storybook and watch how the component looks differently.
  - By default, if a component accepts 2 values, it will be a radio button
  - We can specify `defaultValue` to specific `props` of a component
  - We can add documentation for a component by adding `/** Comments *` in the Props interface and above the component (Note: `// normal comments don't work`)
  - A template is used to create a reusable component which can be used for variants `const Template: Story<ButtonProps> = args => <Button {...args} />;`
    - We can set default value on StoryBook, by setting the value here. 
    - We can also specify default arguments for a variant.
- postcss is used to transform CSS -> AST -> Run it through plugins -> Make it optimised for production
  - postcss `inject: true` -> Load the CSS via Javascript (`styledInject(myCSS)`)
  - [autoprefixer](https://autoprefixer.github.io/) is used to automatically prefix various vendors to the modern CSS. Uses `browserslist`
  - [cssnano](https://cssnano.co/) is used to minify the CSS
- Fixed a bug in parcel 1.12.4 by downgrading
- `devDependencies` is used for developing the package
- `peerDependencies` are the dependencies required to be installed by the consumer project

### References

- [TSDX & Storybook](https://www.youtube.com/watch?v=qSkHRVLcj6U)
- [Basic UI Component library](https://www.youtube.com/watch?v=V_5ImTOmMh0)
- [More Advanced UI Component library guide](https://www.youtube.com/watch?v=XHQi5a0TmMc)
- [Basic project using TSDX](https://www.youtube.com/watch?v=V3XZYC8zmvo)
- [How to use example folder](https://dev.to/g_abud/publish-a-typescript-package-in-under-10-minutes-4940)
- [Parcel bug](https://github.com/parcel-bundler/parcel/issues/5943)
- [Another guide](https://medium.com/fedbites/getting-started-with-tsdx-and-storybook-8b2b27e8d549)
- [Configure TSDX for css](https://tsdx.io/customization)

# Useful prior documentation below

> If you’re new to TypeScript and React, checkout [this handy cheatsheet](https://github.com/sw-yx/react-typescript-cheatsheet/)

## Configuration

Code quality is set up for you with `prettier`, `husky`, and `lint-staged`. Adjust the respective fields in `package.json` accordingly.

### Jest

Jest tests are set up to run with `npm test` or `yarn test`.

### Bundle analysis

Calculates the real cost of your library using [size-limit](https://github.com/ai/size-limit) with `npm run size` and visulize it with `npm run analyze`.

#### React Testing Library

We do not set up `react-testing-library` for you yet, we welcome contributions and documentation on this.

### Rollup

TSDX uses [Rollup](https://rollupjs.org) as a bundler and generates multiple rollup configs for various module formats and build settings. See [Optimizations](#optimizations) for details.

### TypeScript

`tsconfig.json` is set up to interpret `dom` and `esnext` types, as well as `react` for `jsx`. Adjust according to your needs.

## Continuous Integration

### GitHub Actions

Two actions are added by default:

- `main` which installs deps w/ cache, lints, tests, and builds on all pushes against a Node and OS matrix
- `size` which comments cost comparison of your library on every pull request using [size-limit](https://github.com/ai/size-limit)

## Optimizations

Please see the main `tsdx` [optimizations docs](https://github.com/palmerhq/tsdx#optimizations). In particular, know that you can take advantage of development-only optimizations:

```js
// ./types/index.d.ts
declare var __DEV__: boolean;

// inside your code...
if (__DEV__) {
  console.log('foo');
}
```

You can also choose to install and use [invariant](https://github.com/palmerhq/tsdx#invariant) and [warning](https://github.com/palmerhq/tsdx#warning) functions.

## Module Formats

CJS, ESModules, and UMD module formats are supported.

The appropriate paths are configured in `package.json` and `dist/index.js` accordingly. Please report if any issues are found.

## Deploying the Example Playground

The Playground is just a simple [Parcel](https://parceljs.org) app, you can deploy it anywhere you would normally deploy that. Here are some guidelines for **manually** deploying with the Netlify CLI (`npm i -g netlify-cli`):

```bash
cd example # if not already in the example folder
npm run build # builds to dist
netlify deploy # deploy the dist folder
```

Alternatively, if you already have a git repo connected, you can set up continuous deployment with Netlify:

```bash
netlify init
# build command: yarn build && cd example && yarn && yarn build
# directory to deploy: example/dist
# pick yes for netlify.toml
```

## Named Exports

Per Palmer Group guidelines, [always use named exports.](https://github.com/palmerhq/typescript#exports) Code split inside your React app instead of your React library.

## Including Styles

There are many ways to ship styles, including with CSS-in-JS. TSDX has no opinion on this, configure how you like.

For vanilla CSS, you can include it at the root directory and add it to the `files` section in your `package.json`, so that it can be imported separately by your users and run through their bundler's loader.

## Publishing to NPM

We recommend using [np](https://github.com/sindresorhus/np).

## Usage with Lerna

When creating a new package with TSDX within a project set up with Lerna, you might encounter a `Cannot resolve dependency` error when trying to run the `example` project. To fix that you will need to make changes to the `package.json` file _inside the `example` directory_.

The problem is that due to the nature of how dependencies are installed in Lerna projects, the aliases in the example project's `package.json` might not point to the right place, as those dependencies might have been installed in the root of your Lerna project.

Change the `alias` to point to where those packages are actually installed. This depends on the directory structure of your Lerna project, so the actual path might be different from the diff below.

```diff
   "alias": {
-    "react": "../node_modules/react",
-    "react-dom": "../node_modules/react-dom"
+    "react": "../../../node_modules/react",
+    "react-dom": "../../../node_modules/react-dom"
   },
```

An alternative to fixing this problem would be to remove aliases altogether and define the dependencies referenced as aliases as dev dependencies instead. [However, that might cause other problems.](https://github.com/palmerhq/tsdx/issues/64)