## Create React Component Module
- `npm install -D react react-dom typescript @types/react`
- `npx tsc --init`
- Modify `tsconfig.json`
```
{
  "include": ["src"],
  "exclude": [
    "dist",
    "node_modules"
  ],
  "compilerOptions": {
    "module": "esnext",
    "lib": ["dom", "esnext"],
    "importHelpers": true,
    "declaration": true,
    "sourceMap": true,
    "rootDir": "./src",
    "outDir": "./dist/esm",
    "strict": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "moduleResolution": "node",
    "jsx": "react",
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
  }
}
```
- Modify `package.json`:
```
{
  "name": "PACKAGE_NAME",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "tsc"
  },
  "keywords": [],
  "author": "YOUR_NAME",
  "license": "ISC",
  "devDependencies": {
    "@types/react": "^18.0.12",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "typescript": "^4.7.3"
  }
}
```
- Create sample components in `src/components`
- Create `index.ts` inside `src` and export your components there.
- `npm run build`, should generate a `dist` folder at the root.
- `git init` and Create `.gitignore` file with contents of:
```
/node_modules
/dist
# Ignore test-related files
/coverage.data
/coverage/

# Build files
```
- `npm install -D eslint eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser` for linting
- Create an `.eslintrc` file at the root with content of:
```
{
  "root": true,
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "plugins": [
    "@typescript-eslint",
    "react",
    "react-hooks"
  ],
  "rules": {
    "react-hooks/rules-of-hooks": "error",
    "react-hooks/exhaustive-deps": "warn",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/ban-ts-comment": "off",
    "@typescript-eslint/no-explicit-any": "off"
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  },
  "env": {
    "browser": true,
    "node": true
  },
  "globals": {
    "JSX": true
  }
}
```
- Create `.eslintignore`, with content of:
```
/node_modules
/dist
```
- Modify `package.json`, add to script command:
```
"lint": "eslint \"{**/*,*}.{js,ts,jsx,tsx}\""
```
- `npm run lint`, for testing lint
- `npm install -D eslint-config-prettier eslint-plugin-prettier prettier`, for prettier.
- Create `.prettierrc.json`, with content of:
```
{
  "bracketSpacing": true,
  "singleQuote": true,
  "trailingComma": "all",
  "tabWidth": 2,
  "semi": false,
  "printWidth": 120,
  "jsxSingleQuote": true,
  "endOfLine": "auto"
}
```
- Modify `.eslintrc`, reference:
```
"plugins": [
  "@typescript-eslint",
  "prettier",
  "react",
  "react-hooks"
],
"extends": [
  "prettier",
  "plugin:prettier/recommended",
  "eslint:recommended",
  "plugin:react/recommended",
  "plugin:@typescript-eslint/eslint-recommended",
  "plugin:@typescript-eslint/recommended"
],
```
- `npm run lint`, testing lint again.
- Modify `package.json` script command:
```
"prettier": "prettier --write \"{src,tests,example/src}/**/*.{js,ts,jsx,tsx}\""
```
- Well, test linting again.
- `npm install -D jest jest-canvas-mock jest-environment-jsdom ts-jest @types/jest @testing-library/react`
- `npm install --save-dev identity-obj-proxy css-loader`
- Create `jestconfig.json` file at the root, with the content of:
```
{
  "transform": {
    "^.+\\.(t|j)sx?$": "ts-jest"
  },
  "testRegex": "(/tests/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
  "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json", "node"],
  "testEnvironment": "jsdom",
  "moduleNameMapper": {
    "\\.(scss|css)$": "identity-obj-proxy"
  }
}
```
- Create `tests` folder, with a file `sample.test.tsx`.
```
import * as React from 'react'
import { render } from '@testing-library/react'

import 'jest-canvas-mock'

import { Sample } from '../src'

describe('Common render', () => {
  it('renders without crashing', () => {
    render(<Sample />)
  })
})
```
- Modify `package.json` script command:
```
"test": "jest --config jestconfig.json"
```
- Modify `package.json` script command:
```
"build": "npm run build:esm && npm run build:cjs",
"build:esm": "tsc",
"build:cjs": "tsc --module commonjs --outDir dist/cjs",
```
- Modify `package.json`, content of:
```
"main": "./dist/cjs/index.js",
"module": "./dist/esm/index.js",
"types": "./dist/esm/index.d.ts",

"repository": {
  "type": "git",
  "url": "git+https://github.com/KenReyMozo/kenrey-ui.git"
}

"peerDependencies": {
  "react": ">=16",
  "sass": ">=1.69.5"
}

"files": [
  "dist",
  "LICENSE",
  "README.md"
]

"keywords": [
  "kenrey-project",
  "kenrey-ui",
  "kenrey-component"
]

"license": "MIT",
```
- `npm login`
- `npm publish --dry-run`
- `npm publish`

- To add automated build:
- at the root, Create `.github/workflows/publish.yml`, wit the contents:
```
# This is a name of the workflow
name: build
# Controls when the workflow will run
on:
  # Triggers the workflow on published releases
  release:
    types: [published]
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  build:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest
    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:

      - name: Checkout
        # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
        uses: actions/checkout@v3

      - name: Setup Node
        # Setup node environment
        uses: actions/setup-node@v3
        with:
          # Node version. Run "node -v" to check the latest version
          node-version: 16.x
          registry-url: https://registry.npmjs.org/

      - name: Install dependencies
        run: yarn && yarn install

      - name: Build
        run: yarn build

      - name: Publish
        run: yarn publish

        env:
          # We need this to our NPM account
          NODE_AUTH_TOKEN: ${{ secrets.KENREY_UI_AUTOMATION_TOKEN }}
```
- NPM Setup:
- settings -> access tokens
- `Generate New Token`
- Copy the `token`
- GITHUB Setup:
- Repo -> settings
- Secrets -> Actions
- `New repository secret`
- Paste the token
- *NOTE*: secrets.`SECRET_NAME_YOU_SET_IN_GITHUB`

# THIS IS THE REFERENCE FOR THIS STEPS:
https://betterprogramming.pub/how-to-create-and-publish-react-typescript-npm-package-with-demo-and-automated-build-80c40ec28aca

# FOR HANDLING PLAIN CSS
- `npm install --save-dev css-loader style-loader`
- Modify `package.json`, added new command and update build command:
```
"scripts": {
  "build": "npm run build:esm && npm run build:cjs && npm run build:css-components && npm run build:css",
  "build:esm": "tsc",
  "build:cjs": "tsc --module commonjs --outDir dist/cjs",
  "build:css-components": "cp src/components/*.css dist/cjs/components && cp src/components/*.css dist/esm/components",
  "build:css": "cp src/index.css dist/cjs/ && cp src/index.css dist/esm/",
  // Other scripts...
}
```
- Make one entry point for your css files:
 - put your css files in one folder
 - create `index.css` in src, beside the index.ts:
 - import your css files to the `index.css` with `@import '<css-dir>'`
- After installing the package, import your entry point css file to your `app.ts`:
```
import 'your-package-name/dist/cjs/index.css';
```

# FOR HANDLING SCSS FILE / TEMPORARY
- `npm install -D node-sass`
- Modify `package.json`, add new command:
```
"scss": "node-sass src/scss -o src/components"
```