Skip to content

Commit 4fa169b

Browse files
committed
added button and table component
0 parents  commit 4fa169b

25 files changed

+2633
-0
lines changed

.editorconfig

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
insert_final_newline = true
7+
indent_style = space
8+
indent_size = 4
9+
trim_trailing_whitespace = true
10+
11+
[*.json]
12+
indent_size = 2
13+
14+
[*.md]
15+
trim_trailing_whitespace = false
16+
17+
[*.{yml,yaml,ts,tsx}]
18+
indent_size = 2
19+
20+
[docker-compose.yml]
21+
indent_size = 4

.eslintrc.cjs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
root: true,
3+
env: { browser: true, es2020: true },
4+
extends: [
5+
'eslint:recommended',
6+
'plugin:@typescript-eslint/recommended',
7+
'plugin:react-hooks/recommended',
8+
],
9+
ignorePatterns: ['dist', '.eslintrc.cjs'],
10+
parser: '@typescript-eslint/parser',
11+
plugins: ['react-refresh'],
12+
rules: {
13+
'react-refresh/only-export-components': [
14+
'warn',
15+
{ allowConstantExport: true },
16+
],
17+
},
18+
}

.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

.prettierrc

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"semi": true,
3+
"singleQuote": true,
4+
"printWidth": 100,
5+
"trailingComma": "es5",
6+
"arrowParens": "always",
7+
"tabWidth": 2,
8+
"useTabs": false,
9+
"quoteProps": "as-needed",
10+
"jsxSingleQuote": false,
11+
"bracketSpacing": true,
12+
"bracketSameLine": false
13+
}

README.md

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# React + TypeScript + Vite
2+
3+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4+
5+
Currently, two official plugins are available:
6+
7+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9+
10+
## Expanding the ESLint configuration
11+
12+
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13+
14+
- Configure the top-level `parserOptions` property like this:
15+
16+
```js
17+
parserOptions: {
18+
ecmaVersion: 'latest',
19+
sourceType: 'module',
20+
project: ['./tsconfig.json', './tsconfig.node.json'],
21+
tsconfigRootDir: __dirname,
22+
},
23+
```
24+
25+
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
26+
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
27+
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list

index.html

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!doctype html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Tailwind + React</title>
8+
</head>
9+
10+
<body>
11+
<div id="root"></div>
12+
<script type="module" src="/src/main.tsx"></script>
13+
</body>
14+
15+
</html>

package.json

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "tail-react",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "tsc && vite build",
9+
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10+
"preview": "vite preview"
11+
},
12+
"dependencies": {
13+
"@heroicons/react": "^2.0.18",
14+
"react": "^18.2.0",
15+
"react-dom": "^18.2.0",
16+
"tailwind-merge": "^1.14.0"
17+
},
18+
"devDependencies": {
19+
"@types/react": "^18.2.15",
20+
"@types/react-dom": "^18.2.7",
21+
"@typescript-eslint/eslint-plugin": "^6.0.0",
22+
"@typescript-eslint/parser": "^6.0.0",
23+
"@vitejs/plugin-react": "^4.0.3",
24+
"autoprefixer": "^10.4.14",
25+
"eslint": "^8.45.0",
26+
"eslint-plugin-react-hooks": "^4.6.0",
27+
"eslint-plugin-react-refresh": "^0.4.3",
28+
"postcss": "^8.4.27",
29+
"tailwindcss": "^3.3.3",
30+
"typescript": "^5.0.2",
31+
"vite": "^4.4.5"
32+
}
33+
}

postcss.config.js

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export default {
2+
plugins: {
3+
tailwindcss: {},
4+
autoprefixer: {},
5+
},
6+
}

src/App.tsx

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import ButtonExample from '@/Components/Button/Example';
2+
import TableExample from '@/Components/Table/Example';
3+
4+
const App = () => {
5+
return (
6+
<div className="container mx-auto p-12">
7+
{/* <TableExample /> */}
8+
<ButtonExample />
9+
</div>
10+
);
11+
};
12+
13+
export default App;

src/Components/Button/Button.tsx

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import React from 'react';
2+
import { twMerge } from 'tailwind-merge';
3+
4+
interface ButtonProps {
5+
children: React.ReactNode;
6+
variant?: 'primary' | 'secondary' | 'danger';
7+
style: 'fill' | 'outline' | 'link';
8+
type?: 'button' | 'submit' | 'reset';
9+
size: 'small' | 'medium' | 'large';
10+
disabled?: boolean;
11+
as?: React.ElementType;
12+
className?: string;
13+
onClick?: () => void;
14+
href?: string;
15+
target?: string;
16+
rel?: string;
17+
}
18+
19+
const Styles = {
20+
'primary:fill':
21+
'bg-indigo-600 text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600',
22+
'primary:outline':
23+
'bg-white ring-1 ring-inset ring-indigo-600 text-indigo-600 hover:bg-indigo-600 hover:text-white shadow-sm',
24+
'primary:link': 'text-indigo-600 hover:text-indigo-500',
25+
'secondary:fill':
26+
'bg-white ring-1 ring-inset ring-gray-300 hover:bg-gray-50 text-gray-900 shadow-sm',
27+
'secondary:outline': 'bg-white hover:bg-gray-50 text-gray-900 shadow-sm',
28+
'secondary:link': 'text-gray-900 hover:text-gray-500',
29+
'danger:fill': 'bg-red-600 hover:bg-red-500 text-white',
30+
'danger:outline':
31+
'bg-white ring-1 ring-inset ring-red-600 hover:bg-red-600 text-red-600 hover:text-white shadow-sm',
32+
'danger:link': 'text-red-600 hover:text-red-500',
33+
};
34+
35+
const Button: React.FC<ButtonProps> = ({
36+
children,
37+
variant = 'primary',
38+
style = 'fill',
39+
type = 'button',
40+
disabled = false,
41+
as = 'button',
42+
className = '',
43+
onClick,
44+
href,
45+
target,
46+
rel,
47+
size = 'medium',
48+
}) => {
49+
const getSizeStyles = () => {
50+
switch (size) {
51+
case 'small':
52+
return 'rounded px-2 py-1 text-xs';
53+
case 'medium':
54+
return 'rounded-md px-3 py-2 text-sm';
55+
case 'large':
56+
return 'rounded-md px-4 py-3 text-sm';
57+
default:
58+
return '';
59+
}
60+
};
61+
62+
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
63+
if (disabled) {
64+
event.preventDefault();
65+
return;
66+
}
67+
68+
if (onClick) {
69+
onClick();
70+
}
71+
};
72+
73+
const renderButton = () => {
74+
const commonStyles = 'font-semibold focus:outline-none';
75+
const sizeStyles = getSizeStyles();
76+
77+
const disabledStyles = disabled ? 'opacity-50 cursor-not-allowed' : '';
78+
79+
return React.createElement(
80+
as,
81+
{
82+
className: twMerge(
83+
commonStyles,
84+
Styles[`${variant}:${style}`],
85+
sizeStyles,
86+
disabledStyles,
87+
className
88+
),
89+
type,
90+
disabled: disabled,
91+
onClick: handleClick,
92+
href,
93+
target,
94+
rel,
95+
},
96+
children
97+
);
98+
};
99+
100+
return renderButton();
101+
};
102+
103+
export default Button;

0 commit comments

Comments
 (0)