PR-722301: Adding Library Components.
This commit is contained in:
parent
2410a0f8d0
commit
b100dc40c3
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 = {
|
||||||
...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()];
|
config.resolve.plugins = [new TsconfigPathsPlugin()];
|
||||||
return config;
|
return config;
|
||||||
|
142
package-lock.json
generated
142
package-lock.json
generated
@ -1,22 +1,24 @@
|
|||||||
{
|
{
|
||||||
"name": "@aleleba/create-react-component-library",
|
"name": "react-list-ui-library",
|
||||||
"version": "1.2.14",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@aleleba/create-react-component-library",
|
"name": "react-list-ui-library",
|
||||||
"version": "1.2.14",
|
"version": "0.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bin": {
|
|
||||||
"create-react-component-library": "bin/cli.js"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.23.0",
|
"@babel/core": "^7.23.0",
|
||||||
"@babel/preset-env": "^7.22.20",
|
"@babel/preset-env": "^7.22.20",
|
||||||
"@babel/preset-react": "^7.22.15",
|
"@babel/preset-react": "^7.22.15",
|
||||||
"@babel/preset-typescript": "^7.23.0",
|
"@babel/preset-typescript": "^7.23.0",
|
||||||
"@babel/register": "^7.22.15",
|
"@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",
|
"@mdx-js/react": "^2.3.0",
|
||||||
"@storybook/addon-actions": "^7.4.6",
|
"@storybook/addon-actions": "^7.4.6",
|
||||||
"@storybook/addon-docs": "^7.4.6",
|
"@storybook/addon-docs": "^7.4.6",
|
||||||
@ -2892,6 +2894,81 @@
|
|||||||
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==",
|
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/@humanwhocodes/config-array": {
|
||||||
"version": "0.11.11",
|
"version": "0.11.11",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
||||||
@ -22689,6 +22766,57 @@
|
|||||||
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==",
|
"integrity": "sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==",
|
||||||
"dev": true
|
"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": {
|
"@humanwhocodes/config-array": {
|
||||||
"version": "0.11.11",
|
"version": "0.11.11",
|
||||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "react-list-ui-library",
|
"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",
|
"description": "A starter kit for create a React component Library with storybook",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npm run storybook",
|
"start": "npm run storybook",
|
||||||
"build": "webpack",
|
"build": "webpack",
|
||||||
@ -39,6 +39,11 @@
|
|||||||
"@babel/preset-react": "^7.22.15",
|
"@babel/preset-react": "^7.22.15",
|
||||||
"@babel/preset-typescript": "^7.23.0",
|
"@babel/preset-typescript": "^7.23.0",
|
||||||
"@babel/register": "^7.22.15",
|
"@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",
|
"@mdx-js/react": "^2.3.0",
|
||||||
"@storybook/addon-actions": "^7.4.6",
|
"@storybook/addon-actions": "^7.4.6",
|
||||||
"@storybook/addon-docs": "^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 React from 'react';
|
||||||
import { StoryFn, Meta } from '@storybook/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
|
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
|
||||||
export default {
|
export default {
|
||||||
title: 'Example/Card',
|
title: 'List Design System/Input',
|
||||||
component: Card,
|
component: Input,
|
||||||
} as Meta<typeof Card>;
|
} as Meta<typeof Input>;
|
||||||
|
|
||||||
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
|
// 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({});
|
export const Basic = Template.bind({});
|
||||||
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
// More on args: https://storybook.js.org/docs/react/writing-stories/args
|
||||||
Basic.args = {
|
Basic.args = {
|
||||||
title: 'Test Title',
|
placeholder: 'Basic Input',
|
||||||
children: <p>Test Content</p>,
|
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 Repo from './assets/repo.svg';
|
||||||
import StackAlt from './assets/stackalt.svg';
|
import StackAlt from './assets/stackalt.svg';
|
||||||
|
|
||||||
<Meta title="Example/Introduction" />
|
<Meta title="List Design System/Introduction" />
|
||||||
|
|
||||||
<style>
|
<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,
|
"noImplicitAny": false,
|
||||||
"paths": {
|
"paths": {
|
||||||
"@components/*": ["src/components/*"],
|
"@components/*": ["src/components/*"],
|
||||||
"@components": ["src/components"]
|
"@components": ["src/components"],
|
||||||
|
"@styles": ["src/styles"],
|
||||||
|
"@utils/*": ["src/utils/*"],
|
||||||
|
"@utils": ["src/utils"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
|
Loading…
Reference in New Issue
Block a user