gwan-design-system 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/.github/workflows/bump-version.yml +50 -0
  2. package/.github/workflows/publish.yml +43 -0
  3. package/CODEOWNERS +1 -0
  4. package/README.md +54 -0
  5. package/eslint.config.mjs +16 -0
  6. package/next.config.ts +7 -0
  7. package/package.json +27 -0
  8. package/postcss.config.mjs +7 -0
  9. package/public/file.svg +1 -0
  10. package/public/globe.svg +1 -0
  11. package/public/images/empty.png +0 -0
  12. package/public/images/empty_state.png +0 -0
  13. package/public/images/hero.png +0 -0
  14. package/public/images/hero2.png +0 -0
  15. package/public/images/logo.png +0 -0
  16. package/public/images/logo_short.png +0 -0
  17. package/public/images/profile_picture.png +0 -0
  18. package/public/images/success.png +0 -0
  19. package/public/next.svg +1 -0
  20. package/public/vercel.svg +1 -0
  21. package/public/window.svg +1 -0
  22. package/src/app/components-library/page.tsx +8 -0
  23. package/src/app/favicon.ico +0 -0
  24. package/src/app/globals.css +108 -0
  25. package/src/app/layout.tsx +34 -0
  26. package/src/app/page.tsx +5 -0
  27. package/src/components/avatar/index.tsx +109 -0
  28. package/src/components/banner/index.tsx +58 -0
  29. package/src/components/button/index.tsx +61 -0
  30. package/src/components/carousel/index.tsx +58 -0
  31. package/src/components/checkbox/index.tsx +48 -0
  32. package/src/components/chip/index.tsx +22 -0
  33. package/src/components/ellipsis/index.tsx +36 -0
  34. package/src/components/fileUploader/index.tsx +54 -0
  35. package/src/components/filterDropdown/index.tsx +49 -0
  36. package/src/components/icons/arrowLeftSVG/index.tsx +14 -0
  37. package/src/components/icons/checkSVG/index.tsx +14 -0
  38. package/src/components/icons/chevDownSVG/index.tsx +14 -0
  39. package/src/components/icons/chevLeftSVG/index.tsx +14 -0
  40. package/src/components/icons/chevRightSVG/index.tsx +14 -0
  41. package/src/components/icons/circleSVG/index.tsx +14 -0
  42. package/src/components/icons/colorsSVG/index.tsx +21 -0
  43. package/src/components/icons/coversSVG/index.tsx +21 -0
  44. package/src/components/icons/crossSVG/index.tsx +16 -0
  45. package/src/components/icons/dashboardSVG/index.tsx +14 -0
  46. package/src/components/icons/filterSVG/index.tsx +21 -0
  47. package/src/components/icons/index.tsx +17 -0
  48. package/src/components/icons/orderInfoSVG/index.tsx +21 -0
  49. package/src/components/icons/ordersSVG/index.tsx +21 -0
  50. package/src/components/icons/productsSVG/index.tsx +21 -0
  51. package/src/components/icons/signOutSVG/index.tsx +21 -0
  52. package/src/components/icons/templatesSVG/index.tsx +24 -0
  53. package/src/components/icons/uploadSVG/index.tsx +21 -0
  54. package/src/components/input/index.tsx +40 -0
  55. package/src/components/modal/index.tsx +54 -0
  56. package/src/components/navBar/index.tsx +161 -0
  57. package/src/components/pagination/index.tsx +69 -0
  58. package/src/components/radioButton/index.tsx +44 -0
  59. package/src/components/selectDropdown/index.tsx +90 -0
  60. package/src/components/snackBar/index.tsx +46 -0
  61. package/src/components/state/index.tsx +69 -0
  62. package/src/components/table/index.tsx +51 -0
  63. package/src/components/tag/index.tsx +33 -0
  64. package/src/components/timeLine/index.tsx +99 -0
  65. package/src/components/tooltip/index.tsx +70 -0
  66. package/src/index.ts +22 -0
  67. package/src/templates/component-library/avatars/index.tsx +45 -0
  68. package/src/templates/component-library/banners/index.tsx +35 -0
  69. package/src/templates/component-library/buttons/index.tsx +122 -0
  70. package/src/templates/component-library/carousels/index.tsx +38 -0
  71. package/src/templates/component-library/checkboxes/index.tsx +19 -0
  72. package/src/templates/component-library/chips/index.tsx +49 -0
  73. package/src/templates/component-library/ellipsis/index.tsx +20 -0
  74. package/src/templates/component-library/fileUploaders/index.tsx +21 -0
  75. package/src/templates/component-library/filterDropdown/index.tsx +48 -0
  76. package/src/templates/component-library/icons/index.tsx +23 -0
  77. package/src/templates/component-library/index.tsx +179 -0
  78. package/src/templates/component-library/input/index.tsx +35 -0
  79. package/src/templates/component-library/modals/index.tsx +113 -0
  80. package/src/templates/component-library/navBars/index.tsx +91 -0
  81. package/src/templates/component-library/pagination/index.tsx +28 -0
  82. package/src/templates/component-library/radioButtons/index.tsx +33 -0
  83. package/src/templates/component-library/selectDropdown/index.tsx +90 -0
  84. package/src/templates/component-library/snackBars/index.tsx +34 -0
  85. package/src/templates/component-library/states/index.tsx +24 -0
  86. package/src/templates/component-library/tables/index.tsx +143 -0
  87. package/src/templates/component-library/tags/index.tsx +15 -0
  88. package/src/templates/component-library/timeLines/index.tsx +96 -0
  89. package/src/templates/component-library/tooltips/index.tsx +61 -0
  90. package/tsconfig.build.json +16 -0
  91. package/tsconfig.json +27 -0
@@ -0,0 +1,50 @@
1
+ name: Bump Version and Create Release Branch
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ inputs:
6
+ version:
7
+ description: "Version bump type (patch, minor, major, or exact version)"
8
+ required: true
9
+ default: "patch"
10
+
11
+ jobs:
12
+ bump-version:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Checkout code
16
+ uses: actions/checkout@v3
17
+
18
+ - name: Set up Node.js
19
+ uses: actions/setup-node@v3
20
+ with:
21
+ node-version: "18"
22
+
23
+ - name: Configure Git user
24
+ run: |
25
+ git config user.name "github-actions"
26
+ git config user.email "github-actions@github.com"
27
+
28
+ - name: Bump version
29
+ id: bump
30
+ run: |
31
+ set -e
32
+ VERSION_INPUT="${{ github.event.inputs.version }}"
33
+ if [[ "$VERSION_INPUT" =~ ^(patch|minor|major)$ ]]; then
34
+ NEW_VERSION=$(npm version $VERSION_INPUT -m "chore(release): %s")
35
+ else
36
+ NEW_VERSION=$(npm version "$VERSION_INPUT" -m "chore(release): %s")
37
+ fi
38
+ echo "new_version=${NEW_VERSION/v/}" >> $GITHUB_ENV
39
+ echo "NEXT_PUBLIC_APP_VERSION=$(jq -r .version package.json)" > .env
40
+
41
+ - name: Push version tag only (not protected branch)
42
+ run: |
43
+ set -e
44
+ git push origin --tags
45
+
46
+ - name: Create and push release branch
47
+ run: |
48
+ set -e
49
+ git checkout -b release/v${{ env.new_version }}
50
+ git push origin release/v${{ env.new_version }}
@@ -0,0 +1,43 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ jobs:
8
+ publish:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - name: Checkout code
12
+ uses: actions/checkout@v3
13
+
14
+ - name: Set up Node.js
15
+ uses: actions/setup-node@v3
16
+ with:
17
+ node-version: "18"
18
+ registry-url: "https://registry.npmjs.org/"
19
+
20
+ - name: Cache Node.js modules
21
+ uses: actions/cache@v3
22
+ with:
23
+ path: ~/.npm
24
+ key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
25
+ restore-keys: |
26
+ ${{ runner.os }}-node-
27
+
28
+ - name: Install dependencies
29
+ run: npm install
30
+
31
+ - name: Verify package version
32
+ run: npm version
33
+
34
+ - name: Build package
35
+ run: npm run build
36
+
37
+ - name: Dry run publish
38
+ run: npm publish --dry-run
39
+
40
+ - name: Publish package
41
+ run: npm publish --access public
42
+ env:
43
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/CODEOWNERS ADDED
@@ -0,0 +1 @@
1
+ * @gwanfonseka
package/README.md ADDED
@@ -0,0 +1,54 @@
1
+ This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
2
+
3
+ ## Getting Started
4
+
5
+ First, run the development server:
6
+
7
+ ```bash
8
+ npm run dev
9
+ # or
10
+ yarn dev
11
+ # or
12
+ pnpm dev
13
+ # or
14
+ bun dev
15
+ ```
16
+
17
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18
+
19
+ You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
20
+
21
+ This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
22
+
23
+ ## Learn More
24
+
25
+ To learn more about Next.js, take a look at the following resources:
26
+
27
+ - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28
+ - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29
+
30
+ You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
31
+
32
+ ## Deploy on Vercel
33
+
34
+ The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
35
+
36
+ Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
37
+
38
+ ## 🤝 Contributing
39
+
40
+ I welcome contributions via pull requests!\
41
+ However, to keep the project stable and secure:
42
+
43
+ 🔒 Direct pushes to the main branch are not allowed\
44
+ ✅ All changes must go through a pull request\
45
+ 👀 Pull requests require review and approval before merging
46
+
47
+ Want to contribute?
48
+ Fork this repository
49
+
50
+ - Create a feature branch: git checkout -b feature/my-feature
51
+ - Commit your changes and push: git push origin feature/my-feature
52
+ - Open a pull request with a clear description
53
+
54
+ Thanks for helping improve the project! 🙌
@@ -0,0 +1,16 @@
1
+ import { dirname } from "path";
2
+ import { fileURLToPath } from "url";
3
+ import { FlatCompat } from "@eslint/eslintrc";
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+
8
+ const compat = new FlatCompat({
9
+ baseDirectory: __dirname,
10
+ });
11
+
12
+ const eslintConfig = [
13
+ ...compat.extends("next/core-web-vitals", "next/typescript"),
14
+ ];
15
+
16
+ export default eslintConfig;
package/next.config.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { NextConfig } from "next";
2
+
3
+ const nextConfig: NextConfig = {
4
+ /* config options here */
5
+ };
6
+
7
+ export default nextConfig;
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "gwan-design-system",
3
+ "version": "0.1.1",
4
+ "scripts": {
5
+ "dev": "next dev",
6
+ "build": "next build",
7
+ "start": "next start",
8
+ "lint": "next lint"
9
+ },
10
+ "dependencies": {
11
+ "next": "15.3.2",
12
+ "react": "^19.0.0",
13
+ "react-dom": "^19.0.0"
14
+ },
15
+ "devDependencies": {
16
+ "@eslint/eslintrc": "^3",
17
+ "@tailwindcss/postcss": "^4.1.5",
18
+ "@types/node": "^20",
19
+ "@types/react": "^19",
20
+ "@types/react-dom": "^19",
21
+ "eslint": "^9",
22
+ "eslint-config-next": "15.3.2",
23
+ "postcss": "^8.5.3",
24
+ "tailwindcss": "^4",
25
+ "typescript": "^5"
26
+ }
27
+ }
@@ -0,0 +1,7 @@
1
+ const config = {
2
+ plugins: {
3
+ "@tailwindcss/postcss": {},
4
+ },
5
+ };
6
+
7
+ export default config;
@@ -0,0 +1 @@
1
+ <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -0,0 +1 @@
1
+ <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
@@ -0,0 +1,8 @@
1
+ export const dynamic = "force-dynamic";
2
+ import LibraryTemplate from "@/templates/component-library";
3
+
4
+ const ComponentsLibrary = () => {
5
+ return <LibraryTemplate />;
6
+ };
7
+
8
+ export default ComponentsLibrary;
Binary file
@@ -0,0 +1,108 @@
1
+ @import url("https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght@8..144,100..1000&display=swap");
2
+ @import "tailwindcss";
3
+
4
+ :root {
5
+ --background: #ffffff;
6
+ --foreground: #171717;
7
+ --custom-bg: linear-gradient(
8
+ 135deg,
9
+ #9ea593,
10
+ #93a594,
11
+ #93a59c,
12
+ #939fa5,
13
+ #9394a5,
14
+ #9c93a5,
15
+ #a593a4,
16
+ #a59393
17
+ );
18
+ }
19
+
20
+ @media (prefers-color-scheme: light) {
21
+ :root {
22
+ --background: #0a0a0a;
23
+ --foreground: #ededed;
24
+ }
25
+ }
26
+
27
+ body {
28
+ color: var(--foreground);
29
+ background: var(--background);
30
+ font-family: "Roboto Flex", sans-serif;
31
+ font-optical-sizing: auto;
32
+ font-style: normal;
33
+ }
34
+
35
+ @theme {
36
+ --color-background: var(--background);
37
+ --color-foreground: var(--foreground);
38
+
39
+ --color-primary-50: #f2f3ee;
40
+ --color-primary-100: #e1e3da;
41
+ --color-primary-200: #d0d3c6;
42
+ --color-primary-300: #bec3b2;
43
+ --color-primary-400: #adb39e;
44
+ --color-primary-500: #9ea593;
45
+ --color-primary-600: #8c9382;
46
+ --color-primary-700: #787d6e;
47
+ --color-primary-800: #64675a;
48
+ --color-primary-900: #505146;
49
+
50
+ --color-greenola-50: #e6f7e6;
51
+ --color-greenola-100: #c0eac0;
52
+ --color-greenola-200: #99dc99;
53
+ --color-greenola-300: #73cf73;
54
+ --color-greenola-400: #4cc14c;
55
+ --color-greenola-500: #0ba803;
56
+ --color-greenola-600: #0a9602;
57
+ --color-greenola-700: #087f02;
58
+ --color-greenola-800: #066602;
59
+ --color-greenola-900: #044c01;
60
+
61
+ --color-redola-50: #fde7e7;
62
+ --color-redola-100: #fbc0c0;
63
+ --color-redola-200: #f89999;
64
+ --color-redola-300: #f47373;
65
+ --color-redola-400: #f04c4c;
66
+ --color-redola-500: #df0303;
67
+ --color-redola-600: #c90202;
68
+ --color-redola-700: #a50202;
69
+ --color-redola-800: #800202;
70
+ --color-redola-900: #5c0101;
71
+
72
+ --color-blueola-50: #e6f3fa;
73
+ --color-blueola-100: #bfe1f3;
74
+ --color-blueola-200: #99ceeb;
75
+ --color-blueola-300: #73bce4;
76
+ --color-blueola-400: #4caadc;
77
+ --color-blueola-500: #0369a8;
78
+ --color-blueola-600: #025e97;
79
+ --color-blueola-700: #024d7c;
80
+ --color-blueola-800: #013c61;
81
+ --color-blueola-900: #012b46;
82
+
83
+ --color-yellowla-50: #f9f7e6;
84
+ --color-yellowla-100: #f0efc0;
85
+ --color-yellowla-200: #e6e699;
86
+ --color-yellowla-300: #dcdc73;
87
+ --color-yellowla-400: #d1d14c;
88
+ --color-yellowla-500: #a8a203;
89
+ --color-yellowla-600: #969002;
90
+ --color-yellowla-700: #7c7602;
91
+ --color-yellowla-800: #615c01;
92
+ --color-yellowla-900: #464301;
93
+
94
+ --color-neutrola-50: #f8f8f8;
95
+ --color-neutrola-100: #f0f0f0;
96
+ --color-neutrola-200: #e7e7e7;
97
+ --color-neutrola-300: #dedede;
98
+ --color-neutrola-400: #d9d9d9;
99
+ --color-neutrola-500: #bfbfbf;
100
+ --color-neutrola-600: #a6a6a6;
101
+ --color-neutrola-700: #8c8c8c;
102
+ --color-neutrola-800: #737373;
103
+ --color-neutrola-900: #595959;
104
+ }
105
+
106
+ .custom-bg {
107
+ background-image: var(--custom-bg);
108
+ }
@@ -0,0 +1,34 @@
1
+ import "./globals.css";
2
+ import type { Metadata } from "next";
3
+ import { Geist, Geist_Mono } from "next/font/google";
4
+
5
+ const geistSans = Geist({
6
+ variable: "--font-geist-sans",
7
+ subsets: ["latin"],
8
+ });
9
+
10
+ const geistMono = Geist_Mono({
11
+ variable: "--font-geist-mono",
12
+ subsets: ["latin"],
13
+ });
14
+
15
+ export const metadata: Metadata = {
16
+ title: "Create Next App",
17
+ description: "Generated by create next app",
18
+ };
19
+
20
+ export default function RootLayout({
21
+ children,
22
+ }: Readonly<{
23
+ children: React.ReactNode;
24
+ }>) {
25
+ return (
26
+ <html lang="en">
27
+ <body
28
+ className={`${geistSans.variable} ${geistMono.variable} antialiased`}
29
+ >
30
+ {children}
31
+ </body>
32
+ </html>
33
+ );
34
+ }
@@ -0,0 +1,5 @@
1
+ import { redirect } from "next/navigation";
2
+
3
+ export default function Home() {
4
+ redirect("/components-library");
5
+ }
@@ -0,0 +1,109 @@
1
+ import Image from "next/image";
2
+ import { useEffect, useState } from "react";
3
+ import Tooltip, { TOOLTIP_POSITION } from "../tooltip";
4
+
5
+ export enum AVATAR_VARIANT {
6
+ IMAGE_WITH_FULL = "image_with_full",
7
+ INITIALS_WITH_FULL = "initials_with_full",
8
+ IMAGE_ONLY = "image-only",
9
+ INITIALS_ONLY = "initials-only",
10
+ }
11
+
12
+ export interface IAvatar {
13
+ name: string;
14
+ email: string;
15
+ image?: string;
16
+ variant: string;
17
+ }
18
+
19
+ const generatePastelColor = () => {
20
+ const hue = Math.floor(Math.random() * 360);
21
+ const saturation = 60 + Math.random() * 20;
22
+ const lightness = 75 + Math.random() * 10;
23
+
24
+ return `hsl(${hue}, ${saturation}%, ${lightness}%)`;
25
+ };
26
+
27
+ const Avatar = ({ name, email, image, variant }: IAvatar) => {
28
+ const [bgColor, setBgColor] = useState<string>("transparent");
29
+ const [isTooltipInitialVisible, setIsTooltipInitialVisible] = useState(false);
30
+ const [isTooltipImageVisible, setIsTooltipImageVisible] = useState(false);
31
+
32
+ useEffect(() => {
33
+ setBgColor(generatePastelColor());
34
+ }, []);
35
+
36
+ const generateInitials = (name: string) => {
37
+ const nameArray = name.split(" ");
38
+ return nameArray.length > 1
39
+ ? `${nameArray[0].charAt(0)}${nameArray[1].charAt(0)}`
40
+ : nameArray[0].charAt(0);
41
+ };
42
+
43
+ const renderTooltip = (name: string, email: string, isVisible: boolean) => {
44
+ return (
45
+ <Tooltip
46
+ position={TOOLTIP_POSITION.RIGHT}
47
+ label={
48
+ <div className="flex flex-col">
49
+ {name}
50
+ <p className="text-neutrola-300 text-xs">{email}</p>
51
+ </div>
52
+ }
53
+ isVisible={isVisible}
54
+ toolTipWidth="w-36"
55
+ />
56
+ );
57
+ };
58
+
59
+ const renderAvatarImage = () => {
60
+ if (image) {
61
+ return (
62
+ <div
63
+ className="relative"
64
+ onMouseEnter={() => setIsTooltipImageVisible(true)}
65
+ onMouseLeave={() => setIsTooltipImageVisible(false)}
66
+ >
67
+ <Image
68
+ className="rounded-full border border-neutrola-400"
69
+ src={image}
70
+ alt="profile"
71
+ width={60}
72
+ height={60}
73
+ />
74
+ {variant === AVATAR_VARIANT.IMAGE_ONLY &&
75
+ renderTooltip(name, email, isTooltipImageVisible)}
76
+ </div>
77
+ );
78
+ }
79
+
80
+ return (
81
+ <div
82
+ className="size-[60px] flex items-center justify-center rounded-full font-semibold cursor-default relative"
83
+ style={{ backgroundColor: bgColor }}
84
+ onMouseEnter={() => setIsTooltipInitialVisible(true)}
85
+ onMouseLeave={() => setIsTooltipInitialVisible(false)}
86
+ >
87
+ {generateInitials(name)}
88
+ {variant === AVATAR_VARIANT.INITIALS_ONLY &&
89
+ renderTooltip(name, email, isTooltipInitialVisible)}
90
+ </div>
91
+ );
92
+ };
93
+
94
+ return (
95
+ <div className="flex flex-row items-center gap-2">
96
+ {renderAvatarImage()}
97
+
98
+ {(variant === AVATAR_VARIANT.IMAGE_WITH_FULL ||
99
+ variant === AVATAR_VARIANT.INITIALS_WITH_FULL) && (
100
+ <div className="flex flex-col">
101
+ <p className="text-base font-semibold">{name}</p>
102
+ <p className="text-sm text-neutrola-700">{email}</p>
103
+ </div>
104
+ )}
105
+ </div>
106
+ );
107
+ };
108
+
109
+ export default Avatar;
@@ -0,0 +1,58 @@
1
+ export interface IBanner {
2
+ title?: string;
3
+ titleClassName?: string;
4
+ subTitle?: string;
5
+ subTitleClassName?: string;
6
+ contentPlacement?: "left" | "right";
7
+ backgroundImage?: string;
8
+ backgroundColor?: string;
9
+ }
10
+
11
+ const Banner = ({
12
+ title = "",
13
+ subTitle = "",
14
+ contentPlacement = "left",
15
+ backgroundImage = "",
16
+ backgroundColor = "",
17
+ titleClassName = "",
18
+ subTitleClassName = "",
19
+ }: IBanner) => {
20
+ const handleContentPlacement = () => {
21
+ if (contentPlacement === "left") {
22
+ return (
23
+ <>
24
+ <div className="flex flex-col gap-2">
25
+ <p className={titleClassName}>{title}</p>
26
+ <p className={subTitleClassName}>{subTitle}</p>
27
+ </div>
28
+ <div></div>
29
+ </>
30
+ );
31
+ }
32
+
33
+ return (
34
+ <>
35
+ <div></div>
36
+ <div className="flex flex-col gap-2">
37
+ <p className={titleClassName}>{title}</p>
38
+ <p className={subTitleClassName}>{subTitle}</p>
39
+ </div>
40
+ </>
41
+ );
42
+ };
43
+
44
+ return (
45
+ <div
46
+ className={`w-full h-[484px] grid grid-cols-2 items-center px-16 ${backgroundColor} bg-no-repeat bg-cover bg-center`}
47
+ style={
48
+ backgroundImage !== ""
49
+ ? { backgroundImage: `url(${backgroundImage})` }
50
+ : {}
51
+ }
52
+ >
53
+ {handleContentPlacement()}
54
+ </div>
55
+ );
56
+ };
57
+
58
+ export default Banner;
@@ -0,0 +1,61 @@
1
+ import { ReactNode } from "react";
2
+
3
+ export enum BUTTON_VARIANTS {
4
+ PRIMARY = "primary",
5
+ SECONDARY = "secondary",
6
+ TERTIARY = "tertiary",
7
+ }
8
+
9
+ export interface IButton {
10
+ variant?: BUTTON_VARIANTS;
11
+ label?: string;
12
+ onClick: () => void;
13
+ icon?: ReactNode;
14
+ type?: "button" | "submit";
15
+ disabled?: boolean;
16
+ }
17
+
18
+ const Button = ({
19
+ variant = BUTTON_VARIANTS.PRIMARY,
20
+ label,
21
+ onClick,
22
+ icon,
23
+ type = "button",
24
+ disabled = false,
25
+ }: IButton) => {
26
+ const getButtonVariant = (variant: BUTTON_VARIANTS) => {
27
+ switch (variant) {
28
+ case BUTTON_VARIANTS.PRIMARY:
29
+ return disabled
30
+ ? "bg-neutrola-300 text-neutrola-800 cursor-not-allowed"
31
+ : "bg-primary-500 text-white hover:bg-primary-600 active:bg-primary-700";
32
+
33
+ case BUTTON_VARIANTS.SECONDARY:
34
+ return disabled
35
+ ? "bg-neutrola-100 text-neutrola-800 cursor-not-allowed"
36
+ : "bg-neutrola-50 text-primary-700 hover:bg-primary-50 active:bg-primary-100";
37
+ case BUTTON_VARIANTS.TERTIARY:
38
+ return disabled
39
+ ? "text-neutrola-300 border border-neutrola-300 cursor-not-allowed"
40
+ : "bg-transparent text-primary-500 border border-primary-500 hover:bg-neutrola-50 active:bg-neutrola-100";
41
+ }
42
+ };
43
+
44
+ return (
45
+ <button
46
+ className={`${getButtonVariant(variant)} px-4 ${
47
+ label ? "py-2" : "py-4"
48
+ } rounded-lg`}
49
+ type={type}
50
+ onClick={onClick}
51
+ disabled={disabled}
52
+ >
53
+ <div className="flex flex-row gap-2 items-center">
54
+ {icon && <div className="size-5">{icon}</div>}
55
+ {label && <p>{label}</p>}
56
+ </div>
57
+ </button>
58
+ );
59
+ };
60
+
61
+ export default Button;