mirror of
				https://github.com/aleleba/react-list-ui-library.git
				synced 2025-11-04 07:54:36 -06:00 
			
		
		
		
	PR-722301: Adding Library Components.
This commit is contained in:
		
							
								
								
									
										43
									
								
								.github/workflows/npm-publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/npm-publish.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
			
		||||
name: NPM testing and publish package
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [ master ]
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
      - uses: actions/setup-node@v3
 | 
			
		||||
        with:
 | 
			
		||||
          node-version: 16
 | 
			
		||||
          registry-url: https://registry.npmjs.org/
 | 
			
		||||
      - run: npm ci --legacy-peer-deps
 | 
			
		||||
      - run: npm test
 | 
			
		||||
  cypress-run:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
      # Install NPM dependencies, cache them correctly
 | 
			
		||||
      # and run all Cypress tests
 | 
			
		||||
      - name: Cypress install
 | 
			
		||||
        run: npm install --legacy-peer-deps
 | 
			
		||||
      - name: Cypress run
 | 
			
		||||
        uses: cypress-io/github-action@v5 # use the explicit version number
 | 
			
		||||
        with:
 | 
			
		||||
          install: false
 | 
			
		||||
          component: true
 | 
			
		||||
  publish-npm:
 | 
			
		||||
    needs: [ build, cypress-run ]
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
      - uses: actions/setup-node@v3
 | 
			
		||||
        with:
 | 
			
		||||
          node-version: 16
 | 
			
		||||
          registry-url: https://registry.npmjs.org/
 | 
			
		||||
      - run: npm ci --legacy-peer-deps
 | 
			
		||||
      - run: npm publish --access=public
 | 
			
		||||
        env:
 | 
			
		||||
          NODE_AUTH_TOKEN: ${{secrets.npm_token}}
 | 
			
		||||
							
								
								
									
										47
									
								
								.github/workflows/npm-test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								.github/workflows/npm-test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
name: Testing package
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  pull_request:
 | 
			
		||||
    branches: ['*']
 | 
			
		||||
jobs:
 | 
			
		||||
  test:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    strategy:
 | 
			
		||||
      matrix:
 | 
			
		||||
        node-version: [16.x]
 | 
			
		||||
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
 | 
			
		||||
    steps:
 | 
			
		||||
    - uses: actions/checkout@v3
 | 
			
		||||
    - name: Use Node.js 16
 | 
			
		||||
      uses: actions/setup-node@v3
 | 
			
		||||
      with:
 | 
			
		||||
        node-version: 16
 | 
			
		||||
        cache: 'npm'
 | 
			
		||||
        registry-url: https://registry.npmjs.org/
 | 
			
		||||
    - run: npm ci --legacy-peer-deps
 | 
			
		||||
    - run: npm test
 | 
			
		||||
  cypress-run:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
      # Install NPM dependencies, cache them correctly
 | 
			
		||||
      # and run all Cypress tests
 | 
			
		||||
      - name: Cypress install
 | 
			
		||||
        run: npm install --legacy-peer-deps
 | 
			
		||||
      - name: Cypress run
 | 
			
		||||
        uses: cypress-io/github-action@v5 # use the explicit version number
 | 
			
		||||
        with:
 | 
			
		||||
          install: false
 | 
			
		||||
          component: true
 | 
			
		||||
  test-build-package:
 | 
			
		||||
    needs: [ test, cypress-run ]
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    steps:
 | 
			
		||||
      - uses: actions/checkout@v3
 | 
			
		||||
      - uses: actions/setup-node@v3
 | 
			
		||||
        with:
 | 
			
		||||
          node-version: 16
 | 
			
		||||
          registry-url: https://registry.npmjs.org/
 | 
			
		||||
      - run: npm ci --legacy-peer-deps
 | 
			
		||||
      - run: npm run build
 | 
			
		||||
@@ -16,7 +16,9 @@ module.exports = {
 | 
			
		||||
    }),
 | 
			
		||||
    config.resolve.alias = {
 | 
			
		||||
      ...config.resolve.alias,
 | 
			
		||||
      '@components': path.resolve(__dirname, "../src/components/")
 | 
			
		||||
      '@components': path.resolve(__dirname, "../src/components/"),
 | 
			
		||||
      '@styles': path.resolve(__dirname, "../src/styles/"),
 | 
			
		||||
      '@utils': path.resolve(__dirname, "../src/utils/")
 | 
			
		||||
    };
 | 
			
		||||
    config.resolve.plugins = [new TsconfigPathsPlugin()];
 | 
			
		||||
    return config;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										142
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										142
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -1,22 +1,24 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "@aleleba/create-react-component-library",
 | 
			
		||||
  "version": "1.2.14",
 | 
			
		||||
  "name": "react-list-ui-library",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "lockfileVersion": 2,
 | 
			
		||||
  "requires": true,
 | 
			
		||||
  "packages": {
 | 
			
		||||
    "": {
 | 
			
		||||
      "name": "@aleleba/create-react-component-library",
 | 
			
		||||
      "version": "1.2.14",
 | 
			
		||||
      "name": "react-list-ui-library",
 | 
			
		||||
      "version": "0.0.1",
 | 
			
		||||
      "license": "MIT",
 | 
			
		||||
      "bin": {
 | 
			
		||||
        "create-react-component-library": "bin/cli.js"
 | 
			
		||||
      },
 | 
			
		||||
      "devDependencies": {
 | 
			
		||||
        "@babel/core": "^7.23.0",
 | 
			
		||||
        "@babel/preset-env": "^7.22.20",
 | 
			
		||||
        "@babel/preset-react": "^7.22.15",
 | 
			
		||||
        "@babel/preset-typescript": "^7.23.0",
 | 
			
		||||
        "@babel/register": "^7.22.15",
 | 
			
		||||
        "@fortawesome/fontawesome-svg-core": "^6.4.2",
 | 
			
		||||
        "@fortawesome/free-brands-svg-icons": "^6.4.2",
 | 
			
		||||
        "@fortawesome/free-regular-svg-icons": "^6.4.2",
 | 
			
		||||
        "@fortawesome/free-solid-svg-icons": "^6.4.2",
 | 
			
		||||
        "@fortawesome/react-fontawesome": "^0.2.0",
 | 
			
		||||
        "@mdx-js/react": "^2.3.0",
 | 
			
		||||
        "@storybook/addon-actions": "^7.4.6",
 | 
			
		||||
        "@storybook/addon-docs": "^7.4.6",
 | 
			
		||||
@@ -2892,6 +2894,81 @@
 | 
			
		||||
      "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@fortawesome/fontawesome-common-types": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "hasInstallScript": true,
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@fortawesome/fontawesome-svg-core": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "hasInstallScript": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@fortawesome/fontawesome-common-types": "6.4.2"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@fortawesome/free-brands-svg-icons": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-LKOwJX0I7+mR/cvvf6qIiqcERbdnY+24zgpUSouySml+5w8B4BJOx8EhDR/FTKAu06W12fmUIcv6lzPSwYKGGg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "hasInstallScript": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@fortawesome/fontawesome-common-types": "6.4.2"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@fortawesome/free-regular-svg-icons": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-0+sIUWnkgTVVXVAPQmW4vxb9ZTHv0WstOa3rBx9iPxrrrDH6bNLsDYuwXF9b6fGm+iR7DKQvQshUH/FJm3ed9Q==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "hasInstallScript": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@fortawesome/fontawesome-common-types": "6.4.2"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@fortawesome/free-solid-svg-icons": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "hasInstallScript": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@fortawesome/fontawesome-common-types": "6.4.2"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">=6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@fortawesome/react-fontawesome": {
 | 
			
		||||
      "version": "0.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "prop-types": "^15.8.1"
 | 
			
		||||
      },
 | 
			
		||||
      "peerDependencies": {
 | 
			
		||||
        "@fortawesome/fontawesome-svg-core": "~1 || ~6",
 | 
			
		||||
        "react": ">=16.3"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@humanwhocodes/config-array": {
 | 
			
		||||
      "version": "0.11.11",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
 | 
			
		||||
@@ -22689,6 +22766,57 @@
 | 
			
		||||
      "integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "@fortawesome/fontawesome-common-types": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-1DgP7f+XQIJbLFCTX1V2QnxVmpLdKdzzo2k8EmvDOePfchaIGQ9eCHj2up3/jNEbZuBqel5OxiaOJf37TWauRA==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "@fortawesome/fontawesome-svg-core": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-gjYDSKv3TrM2sLTOKBc5rH9ckje8Wrwgx1CxAPbN5N3Fm4prfi7NsJVWd1jklp7i5uSCVwhZS5qlhMXqLrpAIg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@fortawesome/fontawesome-common-types": "6.4.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "@fortawesome/free-brands-svg-icons": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-LKOwJX0I7+mR/cvvf6qIiqcERbdnY+24zgpUSouySml+5w8B4BJOx8EhDR/FTKAu06W12fmUIcv6lzPSwYKGGg==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@fortawesome/fontawesome-common-types": "6.4.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "@fortawesome/free-regular-svg-icons": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-0+sIUWnkgTVVXVAPQmW4vxb9ZTHv0WstOa3rBx9iPxrrrDH6bNLsDYuwXF9b6fGm+iR7DKQvQshUH/FJm3ed9Q==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@fortawesome/fontawesome-common-types": "6.4.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "@fortawesome/free-solid-svg-icons": {
 | 
			
		||||
      "version": "6.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-sYwXurXUEQS32fZz9hVCUUv/xu49PEJEyUOsA51l6PU/qVgfbTb2glsTEaJngVVT8VqBATRIdh7XVgV1JF1LkA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "@fortawesome/fontawesome-common-types": "6.4.2"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "@fortawesome/react-fontawesome": {
 | 
			
		||||
      "version": "0.2.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz",
 | 
			
		||||
      "integrity": "sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "prop-types": "^15.8.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "@humanwhocodes/config-array": {
 | 
			
		||||
      "version": "0.11.11",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "react-list-ui-library",
 | 
			
		||||
  "version": "0.0.1",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "A starter kit for create a React component Library with storybook",
 | 
			
		||||
  "main": "dist/index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
@@ -39,6 +39,11 @@
 | 
			
		||||
    "@babel/preset-react": "^7.22.15",
 | 
			
		||||
    "@babel/preset-typescript": "^7.23.0",
 | 
			
		||||
    "@babel/register": "^7.22.15",
 | 
			
		||||
    "@fortawesome/fontawesome-svg-core": "^6.4.2",
 | 
			
		||||
    "@fortawesome/free-brands-svg-icons": "^6.4.2",
 | 
			
		||||
    "@fortawesome/free-regular-svg-icons": "^6.4.2",
 | 
			
		||||
    "@fortawesome/free-solid-svg-icons": "^6.4.2",
 | 
			
		||||
    "@fortawesome/react-fontawesome": "^0.2.0",
 | 
			
		||||
    "@mdx-js/react": "^2.3.0",
 | 
			
		||||
    "@storybook/addon-actions": "^7.4.6",
 | 
			
		||||
    "@storybook/addon-docs": "^7.4.6",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										21
									
								
								src/components/Button/AddButton/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/components/Button/AddButton/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import React, { FC, MouseEventHandler } from 'react';
 | 
			
		||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 | 
			
		||||
import { faPlus } from '@fortawesome/free-solid-svg-icons';
 | 
			
		||||
import "./style.scss";
 | 
			
		||||
 | 
			
		||||
type TAddButtonProps = {
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the onClick Event of the button.
 | 
			
		||||
   */
 | 
			
		||||
  onClick?: MouseEventHandler<HTMLButtonElement> | undefined
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const AddButton: FC<TAddButtonProps> = ({ onClick }) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <button type="button" className="addButton" onClick={onClick}>
 | 
			
		||||
      <FontAwesomeIcon icon={faPlus} />
 | 
			
		||||
    </button>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { AddButton, TAddButtonProps }
 | 
			
		||||
							
								
								
									
										25
									
								
								src/components/Button/AddButton/style.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/components/Button/AddButton/style.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
.addButton {
 | 
			
		||||
    border: none;
 | 
			
		||||
    height: 40px;
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14),
 | 
			
		||||
        0 3px 1px -2px rgba(0, 0, 0, 0.12), 0 1px 5px 0 rgba(0, 0, 0, 0.2);
 | 
			
		||||
    // background-color: #FF6955;
 | 
			
		||||
    background-color: #71b9f5;
 | 
			
		||||
    border-radius: 25px;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    transition: 0.3s ease-in-out;
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
 | 
			
		||||
    &:hover,
 | 
			
		||||
    &:focus,
 | 
			
		||||
    &:active {
 | 
			
		||||
        // background-color: #bc2d1a;
 | 
			
		||||
        background-color: #185c94;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    svg {
 | 
			
		||||
        color: #ffffff;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								src/components/Button/Buttons.stories.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/components/Button/Buttons.stories.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { StoryFn, Meta } from '@storybook/react';
 | 
			
		||||
import { Button, ButtonTypes } from '@components';
 | 
			
		||||
 | 
			
		||||
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
 | 
			
		||||
export default {
 | 
			
		||||
  title: 'List Design System/Button',
 | 
			
		||||
  component: Button,
 | 
			
		||||
  argTypes: {
 | 
			
		||||
    type: {
 | 
			
		||||
      options: [
 | 
			
		||||
        ButtonTypes.ADD,
 | 
			
		||||
        ButtonTypes.REMOVE
 | 
			
		||||
      ],
 | 
			
		||||
      control: {
 | 
			
		||||
        type: 'select',
 | 
			
		||||
        labels: {
 | 
			
		||||
          [ButtonTypes.ADD]: 'ADD',
 | 
			
		||||
          [ButtonTypes.REMOVE]: 'REMOVE'
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
} as Meta<typeof Button>;
 | 
			
		||||
 | 
			
		||||
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
 | 
			
		||||
const Template: StoryFn<typeof Button> = (args) => <Button {...args} />;
 | 
			
		||||
 | 
			
		||||
export const AddButton = Template.bind({});
 | 
			
		||||
export const RemoveButton = Template.bind({});
 | 
			
		||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
 | 
			
		||||
AddButton.args = {
 | 
			
		||||
  type: ButtonTypes.ADD,
 | 
			
		||||
  onClick: () => alert('AddButton Clicked')
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
RemoveButton.args = {
 | 
			
		||||
  type: ButtonTypes.REMOVE,
 | 
			
		||||
  onClick: () => alert('RemoveButton Clicked')
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										21
									
								
								src/components/Button/RemoveButton/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/components/Button/RemoveButton/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
import React, { FC, MouseEventHandler } from 'react';
 | 
			
		||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 | 
			
		||||
import { faTrashCan } from '@fortawesome/free-solid-svg-icons';
 | 
			
		||||
import "./style.scss";
 | 
			
		||||
 | 
			
		||||
type TRemoveButtonProps = {
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the onClick Event of the button.
 | 
			
		||||
   */
 | 
			
		||||
  onClick?: MouseEventHandler<HTMLButtonElement> | undefined
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const RemoveButton: FC<TRemoveButtonProps> = ({ onClick }) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <button type="button" className="removeButton" onClick={onClick}>
 | 
			
		||||
      <FontAwesomeIcon icon={faTrashCan} />
 | 
			
		||||
    </button>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { RemoveButton, TRemoveButtonProps }
 | 
			
		||||
							
								
								
									
										19
									
								
								src/components/Button/RemoveButton/style.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								src/components/Button/RemoveButton/style.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
			
		||||
.removeButton {
 | 
			
		||||
    border: none;
 | 
			
		||||
    height: 40px;
 | 
			
		||||
    width: 40px;
 | 
			
		||||
    background-color: transparent;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    transition: 0.3s ease-in-out;
 | 
			
		||||
    font-size: 18px;
 | 
			
		||||
    svg {
 | 
			
		||||
        color: #FF6955;
 | 
			
		||||
        transition: 0.3s ease-in-out;
 | 
			
		||||
        &:hover,
 | 
			
		||||
        &:focus,
 | 
			
		||||
        &:active {
 | 
			
		||||
            color: #bc2d1a;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								src/components/Button/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/components/Button/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
import React, { FC, MouseEventHandler } from 'react';
 | 
			
		||||
import { AddButton } from './AddButton';
 | 
			
		||||
import { RemoveButton } from './RemoveButton';
 | 
			
		||||
 | 
			
		||||
type TButtonProps = {
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the title of the card.
 | 
			
		||||
   */
 | 
			
		||||
  type?: ButtonTypes,
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the onClick Event of the button.
 | 
			
		||||
   */
 | 
			
		||||
  onClick?: MouseEventHandler<HTMLButtonElement> | undefined
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum ButtonTypes {
 | 
			
		||||
    ADD = 'ADD',
 | 
			
		||||
    REMOVE = 'REMOVE'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Button: FC<TButtonProps> = ({ type = ButtonTypes.ADD, onClick }) => {
 | 
			
		||||
  return(
 | 
			
		||||
    <>
 | 
			
		||||
      {
 | 
			
		||||
        type === ButtonTypes.ADD &&
 | 
			
		||||
        <AddButton onClick={onClick} />
 | 
			
		||||
      }
 | 
			
		||||
      {
 | 
			
		||||
        type === ButtonTypes.REMOVE &&
 | 
			
		||||
        <RemoveButton onClick={onClick} />
 | 
			
		||||
      }
 | 
			
		||||
    </>
 | 
			
		||||
  )
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { Button, TButtonProps, ButtonTypes }
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
import React, { FC } from "react";
 | 
			
		||||
import "./style.scss";
 | 
			
		||||
 | 
			
		||||
type TCardProps = {
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the title of the card.
 | 
			
		||||
   */
 | 
			
		||||
  title?: string,
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the child component of the card. (The content)
 | 
			
		||||
   */
 | 
			
		||||
  children?: JSX.Element,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const Card: FC<TCardProps> = ({ title, children}) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="Card">
 | 
			
		||||
      <div className="Title">{title}</div>
 | 
			
		||||
 | 
			
		||||
      <div className="Content">{children}</div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { Card, TCardProps }
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
.Card{
 | 
			
		||||
  background-color: #20b0f3;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  border: 3px solid #20b0f3;
 | 
			
		||||
  color: #ffffff;
 | 
			
		||||
  font-weight: 700;
 | 
			
		||||
  margin: 10px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  min-width: 500px;
 | 
			
		||||
  max-width: 500px;
 | 
			
		||||
 | 
			
		||||
  .Title {
 | 
			
		||||
    padding: 15px 0;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .Content {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    padding: 30px;
 | 
			
		||||
    background-color: #ffffff;
 | 
			
		||||
    color: #000000;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/components/ContainerList/ContainerList.stories.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/components/ContainerList/ContainerList.stories.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { StoryFn, Meta } from '@storybook/react';
 | 
			
		||||
import { ContainerList, List, Status } from '@components';
 | 
			
		||||
 | 
			
		||||
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
 | 
			
		||||
export default {
 | 
			
		||||
  title: 'List Design System/ContainerList',
 | 
			
		||||
  component: ContainerList,
 | 
			
		||||
} as Meta<typeof ContainerList>;
 | 
			
		||||
 | 
			
		||||
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
 | 
			
		||||
const Template: StoryFn<typeof ContainerList> = (args) => <ContainerList {...args} />;
 | 
			
		||||
 | 
			
		||||
export const Basic = Template.bind({});
 | 
			
		||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
 | 
			
		||||
Basic.args = {
 | 
			
		||||
  title: 'List Title',
 | 
			
		||||
  children: 
 | 
			
		||||
    <>
 | 
			
		||||
      <List 
 | 
			
		||||
        list={[
 | 
			
		||||
          {
 | 
			
		||||
            name: 'First Item',
 | 
			
		||||
            status: Status.TODO
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'Second Item',
 | 
			
		||||
            status: Status.DONE
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'Third Item',
 | 
			
		||||
            status: Status.TODO
 | 
			
		||||
          },
 | 
			
		||||
          {
 | 
			
		||||
            name: 'Fourth Item',
 | 
			
		||||
            status: Status.DONE
 | 
			
		||||
          }
 | 
			
		||||
        ]}
 | 
			
		||||
        placeholderInput='Add a Item'
 | 
			
		||||
      />
 | 
			
		||||
    </>
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										24
									
								
								src/components/ContainerList/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/components/ContainerList/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
import React, { FC } from 'react';
 | 
			
		||||
import './style.scss';
 | 
			
		||||
 | 
			
		||||
type TContainerListProps = {
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the title of the card.
 | 
			
		||||
   */
 | 
			
		||||
  title?: string,
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the child component of the card. (The content)
 | 
			
		||||
   */
 | 
			
		||||
  children?: JSX.Element,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const ContainerList: FC<TContainerListProps> = ({ title, children }) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="ContainerList">
 | 
			
		||||
      <div className="title">{title}</div>
 | 
			
		||||
      <div className="content">{children}</div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { ContainerList, TContainerListProps }
 | 
			
		||||
							
								
								
									
										29
									
								
								src/components/ContainerList/style.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/components/ContainerList/style.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
			
		||||
.ContainerList{
 | 
			
		||||
  position: relative;
 | 
			
		||||
  background-color: #FEF6F4;
 | 
			
		||||
  border-radius: 10px;
 | 
			
		||||
  color: #000000;
 | 
			
		||||
  font-weight: 200;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  min-width: 100px;
 | 
			
		||||
  max-width: 600px;
 | 
			
		||||
  font-family: 'Roboto', 'sans-serif';
 | 
			
		||||
  left: 50%;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
  transform: translateX(-50%);
 | 
			
		||||
 | 
			
		||||
  .title {
 | 
			
		||||
    padding: 20px 0;
 | 
			
		||||
    display: flex;
 | 
			
		||||
    justify-content: center;
 | 
			
		||||
    font-weight: 500;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  .content {
 | 
			
		||||
    flex: 1;
 | 
			
		||||
    padding: 10px 30px 30px 30px;
 | 
			
		||||
    background-color: #FEF6F4;
 | 
			
		||||
    color: #000000;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,19 +1,19 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { StoryFn, Meta } from '@storybook/react';
 | 
			
		||||
import { Card } from '@components';
 | 
			
		||||
import { Input } from '@components';
 | 
			
		||||
 | 
			
		||||
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
 | 
			
		||||
export default {
 | 
			
		||||
  title: 'Example/Card',
 | 
			
		||||
  component: Card,
 | 
			
		||||
} as Meta<typeof Card>;
 | 
			
		||||
  title: 'List Design System/Input',
 | 
			
		||||
  component: Input,
 | 
			
		||||
} as Meta<typeof Input>;
 | 
			
		||||
 | 
			
		||||
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
 | 
			
		||||
const Template: StoryFn<typeof Card> = (args) => <Card {...args} />;
 | 
			
		||||
const Template: StoryFn<typeof Input> = (args) => <Input {...args} />;
 | 
			
		||||
 | 
			
		||||
export const Basic = Template.bind({});
 | 
			
		||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
 | 
			
		||||
Basic.args = {
 | 
			
		||||
  title: 'Test Title',
 | 
			
		||||
  children: <p>Test Content</p>,
 | 
			
		||||
  placeholder: 'Basic Input',
 | 
			
		||||
  onChange: (e) => { console.log(e.target.value) }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										22
									
								
								src/components/Input/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/components/Input/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
import React, { FC, ChangeEventHandler } from 'react';
 | 
			
		||||
import './style.scss';
 | 
			
		||||
 | 
			
		||||
export type TInputProps = {
 | 
			
		||||
    /**
 | 
			
		||||
     * Is this the text you want to add to the input placeholder
 | 
			
		||||
     */
 | 
			
		||||
    placeholder?: string
 | 
			
		||||
    /**
 | 
			
		||||
     * Is this the onChange event of the input
 | 
			
		||||
     */
 | 
			
		||||
    onChange?: ChangeEventHandler<HTMLInputElement>
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const Input:FC<TInputProps> = ({
 | 
			
		||||
    placeholder = '',
 | 
			
		||||
    onChange = (e) => {}
 | 
			
		||||
}) => {
 | 
			
		||||
    return(
 | 
			
		||||
        <input className='input' placeholder={placeholder} type='text' onChange={onChange} />
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										11
									
								
								src/components/Input/style.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/components/Input/style.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
.input{
 | 
			
		||||
    width: 100%;
 | 
			
		||||
    height: 30px;
 | 
			
		||||
    border: 1px solid #ccc;
 | 
			
		||||
    border-radius: 50px;
 | 
			
		||||
    font-size: 16px;
 | 
			
		||||
    outline: none;
 | 
			
		||||
    &:focus{
 | 
			
		||||
        border: 1px solid #000;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										49
									
								
								src/components/Item/Item.stories.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/components/Item/Item.stories.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
			
		||||
import React, { useState } from 'react';
 | 
			
		||||
import { StoryFn, Meta } from '@storybook/react';
 | 
			
		||||
import { Item, Status } from '@components';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  title: 'List Design System/Item',
 | 
			
		||||
  component: Item,
 | 
			
		||||
  argTypes: {
 | 
			
		||||
    status: {
 | 
			
		||||
      options: [
 | 
			
		||||
        Status.TODO,
 | 
			
		||||
        Status.DONE
 | 
			
		||||
      ],
 | 
			
		||||
      control: {
 | 
			
		||||
        type: 'select',
 | 
			
		||||
        labels: {
 | 
			
		||||
          [Status.TODO]: 'TODO',
 | 
			
		||||
          [Status.DONE]: 'DONE'
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
} as Meta<typeof Item>;
 | 
			
		||||
 | 
			
		||||
const TemplateBasic: StoryFn<typeof Item> = (args) => {
 | 
			
		||||
  return <Item {...args} />;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const TemplateWithHandleChange: StoryFn<typeof Item> = (args) => {
 | 
			
		||||
  const [status, setStatus] = useState(args.status);
 | 
			
		||||
 | 
			
		||||
  const handleChange = (event) => {
 | 
			
		||||
    setStatus(event.target.checked ? Status.DONE : Status.TODO);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  return <Item {...args} status={status} handleChange={handleChange} />;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export const Basic = TemplateBasic.bind({});
 | 
			
		||||
Basic.args = {
 | 
			
		||||
  name: 'Item Name',
 | 
			
		||||
  handleChange: () => {}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const WithHandleChange = TemplateWithHandleChange.bind({});
 | 
			
		||||
WithHandleChange.args = {
 | 
			
		||||
  name: 'Item Name'
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										14
									
								
								src/components/Item/__tests__/Item.test.cy.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/components/Item/__tests__/Item.test.cy.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { Item, Status } from '@components';
 | 
			
		||||
 | 
			
		||||
describe('Testing Card Component', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.mount(<Item name='Item Test' status={Status.DONE} />);
 | 
			
		||||
  })
 | 
			
		||||
  it('Show Item name', () => {
 | 
			
		||||
    cy.get('span').contains('Item Test');
 | 
			
		||||
  })
 | 
			
		||||
  it('Show Item as Checked', () => {
 | 
			
		||||
    cy.get('input').should('be.checked');
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										17
									
								
								src/components/Item/__tests__/Item.test.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/components/Item/__tests__/Item.test.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { render, screen } from '@testing-library/react';
 | 
			
		||||
import { Item, Status } from '@components';
 | 
			
		||||
 | 
			
		||||
describe('<App/> Component', () => {
 | 
			
		||||
    beforeEach(() => {
 | 
			
		||||
        // fetchMock.resetMocks();
 | 
			
		||||
        render(<Item name='Item Test' status={Status.DONE} handleChange={ () => {}} />)
 | 
			
		||||
    });
 | 
			
		||||
    it('Show Item Name', async () => {
 | 
			
		||||
        /* fetchMock.mockResponseOnce(JSON.stringify({
 | 
			
		||||
            //First Data Fetch
 | 
			
		||||
            data: 'data'
 | 
			
		||||
        })); */
 | 
			
		||||
        screen.getByText('Item Test')
 | 
			
		||||
    })
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										63
									
								
								src/components/Item/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/components/Item/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
import React, { FC, ChangeEventHandler } from 'react';
 | 
			
		||||
import './style.scss';
 | 
			
		||||
import { joinClassNames } from '@utils/index';
 | 
			
		||||
 | 
			
		||||
type TItemProps = {
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the name of the item.
 | 
			
		||||
   */
 | 
			
		||||
  name?: string,
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the status of the item.
 | 
			
		||||
   */
 | 
			
		||||
  status?: Status,
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the on Event triggered by the checkbox.
 | 
			
		||||
   */
 | 
			
		||||
  handleChange?: ChangeEventHandler<HTMLInputElement>
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type TItem = {
 | 
			
		||||
  name: string,
 | 
			
		||||
  status: Status
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum Status {
 | 
			
		||||
  TODO = 'TODO',
 | 
			
		||||
  DONE = 'DONE'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const getStatusClass = ({ status }: { status: Status }) => {
 | 
			
		||||
  switch (status) {
 | 
			
		||||
      case 'TODO':
 | 
			
		||||
          return 'to-do';
 | 
			
		||||
      case 'DONE':
 | 
			
		||||
          return 'done';
 | 
			
		||||
      default:
 | 
			
		||||
          return ''
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const Item: FC<TItemProps> = ({
 | 
			
		||||
  name,
 | 
			
		||||
  status = Status.TODO,
 | 
			
		||||
  handleChange
 | 
			
		||||
}) => {
 | 
			
		||||
  const classNames = joinClassNames(getStatusClass({ status }));
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="round">
 | 
			
		||||
      <input
 | 
			
		||||
        id={name}
 | 
			
		||||
        type="checkbox"
 | 
			
		||||
        checked={status === Status.DONE}
 | 
			
		||||
        name={name}
 | 
			
		||||
        className={classNames}
 | 
			
		||||
        onChange={handleChange}
 | 
			
		||||
      />
 | 
			
		||||
      <label htmlFor={name}/>
 | 
			
		||||
      <span className={classNames}>{name}</span>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { Item, TItemProps, TItem, Status }
 | 
			
		||||
							
								
								
									
										57
									
								
								src/components/Item/style.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/components/Item/style.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
.round {
 | 
			
		||||
  position: relative;
 | 
			
		||||
 | 
			
		||||
  label {
 | 
			
		||||
    background-color: #fff;
 | 
			
		||||
    border: 1px solid #ccc;
 | 
			
		||||
    border-radius: 50%;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    height: 19px;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    width: 19px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  label:after {
 | 
			
		||||
    border: 2px solid #fff;
 | 
			
		||||
    border-top: none;
 | 
			
		||||
    border-right: none;
 | 
			
		||||
    content: "";
 | 
			
		||||
    height: 6px;
 | 
			
		||||
    left: 2.5px;
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 4px;
 | 
			
		||||
    transform: rotate(-45deg);
 | 
			
		||||
    width: 11px;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  input[type="checkbox"] {
 | 
			
		||||
    visibility: hidden;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  input[type="checkbox"]:checked + label {
 | 
			
		||||
    background-color: #66bb6a;
 | 
			
		||||
    border-color: #66bb6a;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  input[type="checkbox"]:checked + label:after {
 | 
			
		||||
    opacity: 1;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  span {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    top: 0px;
 | 
			
		||||
    margin-left: 10px;
 | 
			
		||||
    font-family: 'Roboto', 'sans-serif';
 | 
			
		||||
    color: #77838F;
 | 
			
		||||
    font-weight: 400;
 | 
			
		||||
 | 
			
		||||
    &.done {
 | 
			
		||||
      text-decoration: line-through;
 | 
			
		||||
      color: #77838F;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										28
									
								
								src/components/List/List.stories.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/components/List/List.stories.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,28 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { StoryFn, Meta } from '@storybook/react';
 | 
			
		||||
import { List, Status } from '@components';
 | 
			
		||||
 | 
			
		||||
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
 | 
			
		||||
export default {
 | 
			
		||||
  title: 'List Design System/List',
 | 
			
		||||
  component: List,
 | 
			
		||||
} as Meta<typeof List>;
 | 
			
		||||
 | 
			
		||||
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
 | 
			
		||||
const Template: StoryFn<typeof List> = (args) => <List {...args} />;
 | 
			
		||||
 | 
			
		||||
export const Basic = Template.bind({});
 | 
			
		||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
 | 
			
		||||
Basic.args = {
 | 
			
		||||
  list: [
 | 
			
		||||
    {
 | 
			
		||||
      name: 'Item 1',
 | 
			
		||||
      status: Status.TODO
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      name: 'Item 2',
 | 
			
		||||
      status: Status.DONE
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  placeholderInput: 'Add a Item',
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										71
									
								
								src/components/List/index.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/components/List/index.tsx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
import React, { FC, MouseEventHandler, ChangeEventHandler } from 'react';
 | 
			
		||||
import { TItem, Item, ButtonTypes, Button, Input } from '@components';
 | 
			
		||||
import './style.scss';
 | 
			
		||||
import { on } from 'events';
 | 
			
		||||
 | 
			
		||||
type TListProps = {
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the title of the card.
 | 
			
		||||
   */
 | 
			
		||||
  list: TItem[]
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the title of the card.
 | 
			
		||||
   */
 | 
			
		||||
  placeholderInput?: string
 | 
			
		||||
  /**
 | 
			
		||||
     * Is this the onChange event of the input
 | 
			
		||||
     */
 | 
			
		||||
  onChangeInput?: ChangeEventHandler<HTMLInputElement>
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the onClick Event of the button.
 | 
			
		||||
   */
 | 
			
		||||
  onClickAddItem?: MouseEventHandler<HTMLButtonElement> | undefined
 | 
			
		||||
  /**
 | 
			
		||||
   * Is this the onClick Event of the button.
 | 
			
		||||
   */
 | 
			
		||||
  onClickRemoveItem?: MouseEventHandler<HTMLButtonElement> |undefined
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const List: FC<TListProps> = ({
 | 
			
		||||
  list,
 | 
			
		||||
  placeholderInput,
 | 
			
		||||
  onChangeInput,
 | 
			
		||||
  onClickAddItem,
 | 
			
		||||
  onClickRemoveItem
 | 
			
		||||
}) => {
 | 
			
		||||
  return (
 | 
			
		||||
    <div className="List">
 | 
			
		||||
      <table>
 | 
			
		||||
        <tbody>
 | 
			
		||||
          { list !== undefined && list.map((item, index) => (
 | 
			
		||||
            <tr key={index}>
 | 
			
		||||
              <td><Item name={item.name} status={item.status} /></td>
 | 
			
		||||
              <td>
 | 
			
		||||
                <div className="delete-button-container">
 | 
			
		||||
                  <Button 
 | 
			
		||||
                    type={ButtonTypes.REMOVE}
 | 
			
		||||
                    onClick={onClickRemoveItem}
 | 
			
		||||
                  />
 | 
			
		||||
                </div>
 | 
			
		||||
              </td>
 | 
			
		||||
            </tr>
 | 
			
		||||
          ))}
 | 
			
		||||
        </tbody>
 | 
			
		||||
      </table>
 | 
			
		||||
      <div>
 | 
			
		||||
        <Input 
 | 
			
		||||
          placeholder={placeholderInput}
 | 
			
		||||
          onChange={onChangeInput}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
      <div className="button-container">
 | 
			
		||||
        <Button 
 | 
			
		||||
          type={ButtonTypes.ADD}
 | 
			
		||||
          onClick={onClickAddItem}
 | 
			
		||||
        />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export { List, TListProps }
 | 
			
		||||
							
								
								
									
										40
									
								
								src/components/List/style.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/components/List/style.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
.List {
 | 
			
		||||
  position: relative;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  max-width: 600px;
 | 
			
		||||
  padding: 15px;
 | 
			
		||||
  border-radius: 8px;
 | 
			
		||||
  background: #FFF;
 | 
			
		||||
  box-shadow: 0px 2px 48px 0px rgba(0, 0, 0, 0.08);
 | 
			
		||||
  //left: 50%;
 | 
			
		||||
  //transform: translateX(50%);
 | 
			
		||||
 | 
			
		||||
  table {
 | 
			
		||||
    margin: 10px 0 30px 0;
 | 
			
		||||
    tbody {
 | 
			
		||||
      tr {
 | 
			
		||||
        td {
 | 
			
		||||
          padding: 5px 0 5px 0;
 | 
			
		||||
          border-bottom: 1px solid #E0E0E0;
 | 
			
		||||
          font-size: 14px;
 | 
			
		||||
          color: #4A4A4A;
 | 
			
		||||
          font-weight: 500;
 | 
			
		||||
          line-height: 1.5;
 | 
			
		||||
 | 
			
		||||
          .delete-button-container{
 | 
			
		||||
            position: relative;
 | 
			
		||||
            width: 100%;
 | 
			
		||||
            left: 65%;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  .button-container {
 | 
			
		||||
    position: relative;
 | 
			
		||||
    left: 90%;
 | 
			
		||||
    top: 35px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { Card } from '@components';
 | 
			
		||||
 | 
			
		||||
describe('Testing Card Component', () => {
 | 
			
		||||
  beforeEach(() => {
 | 
			
		||||
    cy.mount(<Card title='Test Title'><p>Test Content</p></Card>);
 | 
			
		||||
  })
 | 
			
		||||
  it('Show Title', () => {
 | 
			
		||||
    cy.get('div').contains('Test Title');
 | 
			
		||||
  })
 | 
			
		||||
  it('Show Child Component', () => {
 | 
			
		||||
    cy.get('p').contains('Test Content');
 | 
			
		||||
  })
 | 
			
		||||
})
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { render, screen } from '@testing-library/react';
 | 
			
		||||
import { Card } from '@components';
 | 
			
		||||
 | 
			
		||||
describe('<App/> Component', () => {
 | 
			
		||||
    beforeEach(() => {
 | 
			
		||||
        // fetchMock.resetMocks();
 | 
			
		||||
        render(<Card title='Test Title'><p>Test Content</p></Card>)
 | 
			
		||||
    });
 | 
			
		||||
    it('Show Title', async () => {
 | 
			
		||||
        /* fetchMock.mockResponseOnce(JSON.stringify({
 | 
			
		||||
            //First Data Fetch
 | 
			
		||||
            data: 'data'
 | 
			
		||||
        })); */
 | 
			
		||||
        screen.getByText('Test Title')
 | 
			
		||||
    })
 | 
			
		||||
    it('Show Child Component', async () => {
 | 
			
		||||
        /* fetchMock.mockResponseOnce(JSON.stringify({
 | 
			
		||||
            //First Data Fetch
 | 
			
		||||
            data: 'data'
 | 
			
		||||
        })); */
 | 
			
		||||
        screen.getByText('Test Content')
 | 
			
		||||
    })
 | 
			
		||||
})
 | 
			
		||||
@@ -1 +1,7 @@
 | 
			
		||||
export * from './Card';
 | 
			
		||||
import '@styles/global.scss'
 | 
			
		||||
 | 
			
		||||
export * from './ContainerList';
 | 
			
		||||
export * from './List';
 | 
			
		||||
export * from './Item';
 | 
			
		||||
export * from './Button';
 | 
			
		||||
export * from './Input';
 | 
			
		||||
@@ -8,7 +8,7 @@ import Plugin from './assets/plugin.svg';
 | 
			
		||||
import Repo from './assets/repo.svg';
 | 
			
		||||
import StackAlt from './assets/stackalt.svg';
 | 
			
		||||
 | 
			
		||||
<Meta title="Example/Introduction" />
 | 
			
		||||
<Meta title="List Design System/Introduction" />
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
  {`
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								src/styles/global.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/styles/global.scss
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
@import url('https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap');
 | 
			
		||||
							
								
								
									
										1
									
								
								src/utils/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/utils/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
export const joinClassNames = (...classes: string[]) => classes.filter(className => className).join(' ')
 | 
			
		||||
@@ -33,7 +33,10 @@
 | 
			
		||||
      "noImplicitAny": false,
 | 
			
		||||
      "paths": {
 | 
			
		||||
        "@components/*": ["src/components/*"],
 | 
			
		||||
        "@components": ["src/components"]
 | 
			
		||||
        "@components": ["src/components"],
 | 
			
		||||
        "@styles": ["src/styles"],
 | 
			
		||||
        "@utils/*": ["src/utils/*"],
 | 
			
		||||
        "@utils": ["src/utils"]
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "include": [
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user