├── .eslintrc.cjs
├── .gitignore
├── README.md
├── index.html
├── package-lock.json
├── package.json
├── public
└── vite.svg
├── src
├── App.jsx
├── Layout.css
├── Layout.jsx
├── assets
│ └── react.svg
├── components
│ ├── accordions
│ │ ├── ImageAccordion
│ │ │ ├── ImageAccordion.jsx
│ │ │ └── styles.css
│ │ ├── ImageAccordionExample
│ │ │ ├── 1.jpg
│ │ │ ├── 2.jpg
│ │ │ ├── 3.jpg
│ │ │ ├── 4.jpg
│ │ │ ├── 5.jpg
│ │ │ ├── 6.jpg
│ │ │ ├── ImageAccordionExample.jsx
│ │ │ └── styles.css
│ │ └── index.js
│ ├── buttons
│ │ ├── DeleteButton
│ │ │ ├── DeleteButton.jsx
│ │ │ └── styles.css
│ │ ├── FabButton
│ │ │ ├── FabButton.css
│ │ │ └── FabButton.jsx
│ │ ├── TrashButton
│ │ │ ├── TrashButton.css
│ │ │ ├── TrashButton.jsx
│ │ │ ├── paper.svg
│ │ │ └── shredded.svg
│ │ └── index.js
│ ├── cards
│ │ ├── Card1
│ │ │ ├── Card1.jsx
│ │ │ └── styles.css
│ │ ├── Card2
│ │ │ ├── Card2.css
│ │ │ ├── Card2.jsx
│ │ │ ├── Card2Example.jsx
│ │ │ └── image.jpg
│ │ ├── Card3
│ │ │ ├── Card3.css
│ │ │ ├── Card3.jsx
│ │ │ ├── Card3Example.css
│ │ │ ├── Card3Example.jsx
│ │ │ ├── avatar.png
│ │ │ └── logo.svg
│ │ └── index.js
│ ├── carousels
│ │ ├── Carousel1
│ │ │ ├── 1.jpg
│ │ │ ├── 2.jpg
│ │ │ ├── 3.jpg
│ │ │ ├── 4.jpg
│ │ │ ├── 5.jpg
│ │ │ ├── Carousel1.jsx
│ │ │ └── styles.css
│ │ ├── Carousel2
│ │ │ ├── 1.jpg
│ │ │ ├── 2.jpg
│ │ │ ├── 3.jpg
│ │ │ ├── 4.jpg
│ │ │ ├── 5.jpg
│ │ │ ├── 6.jpg
│ │ │ ├── 7.jpg
│ │ │ ├── 8.jpg
│ │ │ ├── 9.jpg
│ │ │ ├── Carousel2.jsx
│ │ │ └── styles.css
│ │ └── index.js
│ ├── controls
│ │ ├── AutoSuggest
│ │ │ ├── AutoSuggest.jsx
│ │ │ ├── Joegle.svg
│ │ │ └── styles.css
│ │ ├── EditableText
│ │ │ ├── EditableText.css
│ │ │ ├── EditableText.jsx
│ │ │ ├── EditableTextExample.css
│ │ │ ├── EditableTextExample.jsx
│ │ │ └── image.jpg
│ │ ├── PasswordStrength
│ │ │ ├── PasswordStrength.jsx
│ │ │ ├── logo.svg
│ │ │ └── styles.css
│ │ ├── PasswordVisibility
│ │ │ ├── Password.css
│ │ │ ├── Password.jsx
│ │ │ ├── PasswordVisibilityExample.css
│ │ │ ├── PasswordVisibilityExample.jsx
│ │ │ └── bg.svg
│ │ └── index.js
│ ├── dropdowns
│ │ ├── Dropdown1
│ │ │ ├── Dropdown1.css
│ │ │ ├── Dropdown1.jsx
│ │ │ └── Dropdown1Example.jsx
│ │ ├── Dropdown2
│ │ │ ├── Dropdown2.css
│ │ │ ├── Dropdown2.jsx
│ │ │ ├── Dropdown2Example.css
│ │ │ ├── Dropdown2Example.jsx
│ │ │ ├── icons.png
│ │ │ ├── joe.png
│ │ │ └── logo.svg
│ │ ├── Dropdown3
│ │ │ ├── Dropdown3.css
│ │ │ └── Dropdown3.jsx
│ │ ├── Dropdown4
│ │ │ ├── Dropdown4.css
│ │ │ ├── Dropdown4.jsx
│ │ │ ├── Dropdown4Example.css
│ │ │ └── Dropdown4Example.jsx
│ │ └── index.js
│ ├── gsap
│ │ ├── ScrollReveal
│ │ │ ├── ScrollReveal.jsx
│ │ │ └── styles.css
│ │ ├── TypedMessage
│ │ │ ├── TypedMessage.css
│ │ │ ├── TypedMessage.jsx
│ │ │ ├── TypedMessageExample.css
│ │ │ ├── TypedMessageExample.jsx
│ │ │ ├── image.jpg
│ │ │ ├── logo.svg
│ │ │ └── video.mp4
│ │ └── index.js
│ ├── index.js
│ ├── libraries
│ │ ├── index.js
│ │ ├── rc-slider
│ │ │ ├── RcSlider.css
│ │ │ └── RcSlider.jsx
│ │ ├── react-dropzone
│ │ │ ├── ReactDropzone.css
│ │ │ ├── ReactDropzone.jsx
│ │ │ └── icon.svg
│ │ └── react-xarrows
│ │ │ ├── ReactXarrows.css
│ │ │ └── ReactXarrows.jsx
│ ├── logins
│ │ ├── Login1
│ │ │ ├── Login1.jsx
│ │ │ ├── logo.svg
│ │ │ └── styles.css
│ │ └── index.js
│ ├── modals
│ │ ├── Modal1
│ │ │ ├── Modal1.jsx
│ │ │ ├── logo.svg
│ │ │ └── styles.css
│ │ ├── Modal2
│ │ │ ├── Modal2 copy.css
│ │ │ ├── Modal2.css
│ │ │ ├── Modal2.jsx
│ │ │ ├── Modal2Example.css
│ │ │ ├── Modal2Example.jsx
│ │ │ └── logo.svg
│ │ └── index.js
│ ├── navbars
│ │ ├── Navbar1
│ │ │ ├── 1.svg
│ │ │ ├── 2.svg
│ │ │ ├── 3.svg
│ │ │ ├── 4.svg
│ │ │ ├── 5.svg
│ │ │ ├── 6.svg
│ │ │ ├── Navbar1.css
│ │ │ └── Navbar1.jsx
│ │ ├── Navbar2
│ │ │ ├── Navbar2.css
│ │ │ └── Navbar2.jsx
│ │ ├── Navbar3
│ │ │ ├── Navbar3.css
│ │ │ ├── Navbar3.jsx
│ │ │ └── avatar.png
│ │ └── index.js
│ ├── parallax
│ │ ├── index.js
│ │ └── parallax-1
│ │ │ ├── Parallax1.jsx
│ │ │ ├── bg.png
│ │ │ └── styles.css
│ ├── sidebars
│ │ ├── Sidebar1
│ │ │ ├── Sidebar1.jsx
│ │ │ └── styles.css
│ │ ├── Sidebar2
│ │ │ ├── Sidebar2.jsx
│ │ │ ├── logo.svg
│ │ │ └── styles.css
│ │ ├── Sidebar3
│ │ │ ├── Sidebar3.jsx
│ │ │ ├── bg.jpeg
│ │ │ ├── logo.svg
│ │ │ └── styles.css
│ │ ├── Sidebar4
│ │ │ ├── Sidebar4.css
│ │ │ ├── Sidebar4.jsx
│ │ │ └── logo.png
│ │ ├── Sidebar5
│ │ │ ├── Sidebar5.css
│ │ │ ├── Sidebar5.jsx
│ │ │ └── logo.svg
│ │ ├── Sidebar6
│ │ │ ├── Sidebar6.css
│ │ │ ├── Sidebar6.jsx
│ │ │ └── logo.svg
│ │ ├── Sidebar7
│ │ │ ├── Sidebar7.jsx
│ │ │ ├── logo.svg
│ │ │ └── styles.css
│ │ ├── Sidebar8
│ │ │ ├── Sidebar8 copy.css
│ │ │ ├── Sidebar8.css
│ │ │ ├── Sidebar8.jsx
│ │ │ └── logo.svg
│ │ └── index.js
│ ├── signups
│ │ └── index.js
│ ├── tables
│ │ ├── Table1
│ │ │ ├── Table1.css
│ │ │ ├── Table1.jsx
│ │ │ ├── Table1Example.css
│ │ │ ├── Table1Example.jsx
│ │ │ ├── bg.svg
│ │ │ └── logo.svg
│ │ ├── Table2
│ │ │ ├── Table2.css
│ │ │ ├── Table2.jsx
│ │ │ ├── Table2Example.css
│ │ │ └── Table2Example.jsx
│ │ ├── Table3
│ │ │ ├── Table3.css
│ │ │ ├── Table3.jsx
│ │ │ ├── Table3Example.css
│ │ │ ├── Table3Example.jsx
│ │ │ └── image.svg
│ │ └── index.js
│ └── widgets
│ │ ├── Widget1
│ │ ├── Widget1.jsx
│ │ └── styles.css
│ │ ├── Widget2
│ │ ├── Widget2.jsx
│ │ ├── styles copy.css
│ │ └── styles.css
│ │ └── index.js
├── index.css
├── main.jsx
└── routes.jsx
├── vite.config.js
└── yarn.lock
/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | env: { browser: true, es2020: true },
4 | extends: [
5 | 'eslint:recommended',
6 | 'plugin:react/recommended',
7 | 'plugin:react/jsx-runtime',
8 | 'plugin:react-hooks/recommended',
9 | ],
10 | ignorePatterns: ['dist', '.eslintrc.cjs'],
11 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
12 | settings: { react: { version: '18.2' } },
13 | plugins: ['react-refresh'],
14 | rules: {
15 | 'react-refresh/only-export-components': [
16 | 'warn',
17 | { allowConstantExport: true },
18 | ],
19 | },
20 | }
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
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?
25 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React + 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 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | React Components
8 |
9 |
10 |
11 |
15 |
19 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-components",
3 | "private": true,
4 | "version": "0.0.0",
5 | "type": "module",
6 | "scripts": {
7 | "dev": "vite --open",
8 | "build": "vite build",
9 | "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
10 | "preview": "vite preview"
11 | },
12 | "dependencies": {
13 | "@gsap/react": "^2.1.0",
14 | "framer-motion": "^11.0.18",
15 | "gsap": "^3.13.0",
16 | "rc-slider": "^10.6.2",
17 | "react": "^18.2.0",
18 | "react-dom": "^18.2.0",
19 | "react-draggable": "^4.4.6",
20 | "react-dropzone": "^14.3.5",
21 | "react-router-dom": "^6.22.3",
22 | "react-toastify": "^11.0.5",
23 | "react-xarrows": "^2.0.2",
24 | "swiper": "^11.1.4"
25 | },
26 | "devDependencies": {
27 | "@types/react": "^18.2.43",
28 | "@types/react-dom": "^18.2.17",
29 | "@vitejs/plugin-react": "^4.2.1",
30 | "eslint": "^8.55.0",
31 | "eslint-plugin-react": "^7.33.2",
32 | "eslint-plugin-react-hooks": "^4.6.0",
33 | "eslint-plugin-react-refresh": "^0.4.5",
34 | "vite": "^5.0.8"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/public/vite.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/App.jsx:
--------------------------------------------------------------------------------
1 | import { createBrowserRouter, RouterProvider } from "react-router-dom";
2 | import { Layout } from "./Layout";
3 | import { routes } from "./routes";
4 |
5 | const router = createBrowserRouter([
6 | {
7 | path: "/",
8 | element: ,
9 | },
10 | ...routes,
11 | ]);
12 |
13 | function App() {
14 | return ;
15 | }
16 |
17 | export default App;
18 |
--------------------------------------------------------------------------------
/src/Layout.jsx:
--------------------------------------------------------------------------------
1 | import { Link, useNavigate } from "react-router-dom";
2 | import { routes } from "./routes";
3 | import "./Layout.css";
4 |
5 | export const Layout = () => {
6 | const sortedRoutes = routes.sort((a, b) => a.name.localeCompare(b.name));
7 |
8 | const navigate = useNavigate();
9 |
10 | return (
11 |
12 |
32 |
33 |
34 |
35 |
36 |
37 | Name
38 |
39 |
40 |
41 | {sortedRoutes.map((route) => (
42 | navigate(route.path)} key={route.path}>
43 |
44 | {route.name}
45 |
46 |
47 | ))}
48 |
49 |
50 |
51 |
52 |
53 | );
54 | };
55 |
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordion/ImageAccordion.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./styles.css";
3 |
4 | export const ImageAccordion = ({ items }) => {
5 | const [active, setActive] = useState(0);
6 |
7 | const handleToggle = (index) => setActive(index);
8 |
9 | return (
10 |
11 | {items.map((item, index) => {
12 | const isActive = active === index ? "active" : "";
13 | return (
14 | handleToggle(index)}
18 | >
19 |
20 |
21 |
photo_camera
22 |
23 |
{item.header}
24 |
{item.text}
25 |
26 |
27 |
28 | );
29 | })}
30 |
31 | );
32 | };
33 |
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordion/styles.css:
--------------------------------------------------------------------------------
1 | .image-accordion {
2 | display: flex;
3 | gap: 10px;
4 | cursor: pointer;
5 | }
6 |
7 | .image-accordion-item {
8 | position: relative;
9 | overflow: hidden;
10 | width: 64px;
11 | height: 500px;
12 | border-radius: 36px;
13 | display: flex;
14 | align-items: flex-end;
15 | opacity: 0.5;
16 | transition: 0.5s;
17 | }
18 |
19 | .image-accordion-item:hover {
20 | opacity: 0.75;
21 | }
22 |
23 | .image-accordion :is(h2, p) {
24 | margin: 0;
25 | }
26 |
27 | .image-accordion-item h2 {
28 | font-size: 24px;
29 | font-weight: 400;
30 | color: rgb(255 255 255 / 96%);
31 | }
32 |
33 | .image-accordion-item p {
34 | color: rgb(255 255 255 / 66%);
35 | }
36 |
37 | .image-accordion-item.active {
38 | width: 400px;
39 | opacity: 1;
40 | }
41 |
42 | .image-accordion-item .material-symbols-outlined {
43 | display: grid;
44 | place-items: center;
45 | width: 50px;
46 | height: 50px;
47 | color: rgb(0 0 0 / 80%);
48 | background: rgb(255 255 255 / 70%);
49 | border-radius: 50%;
50 | font-size: 28px;
51 | }
52 |
53 | .image-accordion-item .content {
54 | position: absolute;
55 | bottom: 0;
56 | left: 0;
57 | width: 400px;
58 | z-index: 1;
59 | opacity: 0;
60 | visibility: hidden;
61 | padding: 100px 0 20px 20px;
62 | display: flex;
63 | align-items: center;
64 | gap: 14px;
65 | background: linear-gradient(to bottom, rgb(0 0 0 / 0%), rgb(0 0 0 / 80%));
66 | transition: 0.25s;
67 | }
68 |
69 | .image-accordion-item.active .content {
70 | opacity: 1;
71 | visibility: visible;
72 | }
73 |
74 | .image-accordion-item img {
75 | position: absolute;
76 | z-index: 0;
77 | top: 50%;
78 | left: 50%;
79 | translate: -50% -50%;
80 | height: 150%;
81 | filter: grayscale(0.6);
82 | }
83 |
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordionExample/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/accordions/ImageAccordionExample/1.jpg
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordionExample/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/accordions/ImageAccordionExample/2.jpg
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordionExample/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/accordions/ImageAccordionExample/3.jpg
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordionExample/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/accordions/ImageAccordionExample/4.jpg
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordionExample/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/accordions/ImageAccordionExample/5.jpg
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordionExample/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/accordions/ImageAccordionExample/6.jpg
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordionExample/ImageAccordionExample.jsx:
--------------------------------------------------------------------------------
1 | import { ImageAccordion } from "../ImageAccordion/ImageAccordion";
2 | import image1 from "./6.jpg";
3 | import image2 from "./2.jpg";
4 | import image3 from "./3.jpg";
5 | import image4 from "./4.jpg";
6 | import image5 from "./5.jpg";
7 |
8 | const coolImages = [
9 | {
10 | header: "Canada",
11 | image: image2,
12 | text: `Image description`,
13 | },
14 |
15 | {
16 | header: "New Zealand",
17 | image: image1,
18 | text: `Image description`,
19 | },
20 |
21 | {
22 | header: "Indonesia",
23 | image: image4,
24 | text: `Image description`,
25 | },
26 | {
27 | header: "South Africa",
28 | image: image5,
29 | text: `Image description`,
30 | },
31 | {
32 | header: "Spain",
33 | image: image3,
34 | text: `Image description`,
35 | },
36 | ];
37 |
38 | export const ImageAccordionExample = () => (
39 |
42 | );
43 |
--------------------------------------------------------------------------------
/src/components/accordions/ImageAccordionExample/styles.css:
--------------------------------------------------------------------------------
1 | .page.image-accordion-page {
2 | background: #141415;
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/accordions/index.js:
--------------------------------------------------------------------------------
1 | export * from "./ImageAccordion/ImageAccordion";
2 | export * from "./ImageAccordionExample/ImageAccordionExample";
3 |
--------------------------------------------------------------------------------
/src/components/buttons/DeleteButton/DeleteButton.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./styles.css";
3 |
4 | export const DeleteButton = () => {
5 | const [isDeleting, setIsDeleting] = useState(false);
6 | const [isDeleted, setIsDeleted] = useState(false);
7 |
8 | const handleClick = () => {
9 | setIsDeleting(true);
10 | // do something async
11 | setTimeout(() => {
12 | setIsDeleting(false);
13 | setIsDeleted(true);
14 | setTimeout(() => {
15 | setIsDeleted(false);
16 | }, 1250);
17 | }, 2500);
18 | };
19 |
20 | return (
21 |
22 |
27 |
28 | {isDeleting || isDeleted ? "Deleting" : "Delete"}
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | );
40 | };
41 |
--------------------------------------------------------------------------------
/src/components/buttons/DeleteButton/styles.css:
--------------------------------------------------------------------------------
1 | .page-wrapper {
2 | background: #000;
3 | }
4 |
5 | .delete-button {
6 | display: flex;
7 | align-items: center;
8 | justify-content: center;
9 | border-radius: 10px;
10 | border: 0;
11 | background: #fc3b51;
12 | font-size: 24px;
13 | font-weight: 400;
14 | font-family: "Euclid Circular A";
15 | color: #f9f9f9;
16 | padding: 0 10px 0 32px;
17 | height: 74px;
18 | text-align: left;
19 | cursor: pointer;
20 | outline: none;
21 | transition: 0.3s;
22 | }
23 |
24 | .delete-button .button-text {
25 | display: block;
26 | text-align: center;
27 | min-width: 94px;
28 | }
29 |
30 | .delete-button .animation {
31 | position: relative;
32 | overflow: hidden;
33 | display: grid;
34 | place-items: center;
35 | width: 64px;
36 | height: 74px;
37 | flex: 0 0 64px;
38 | min-width: 0;
39 | }
40 |
41 | .delete-button .can {
42 | overflow: hidden;
43 | position: relative;
44 | translate: 0 2px;
45 | width: 20px;
46 | height: 22px;
47 | border-bottom-left-radius: 5px;
48 | border-bottom-right-radius: 5px;
49 | border: 2px solid #ffffff;
50 | border-top: 0;
51 | }
52 |
53 | @keyframes lid-open {
54 | 0% {
55 | rotate: 0;
56 | }
57 | 15%,
58 | 90% {
59 | rotate: -75deg;
60 | translate: -70% -20%;
61 | width: 20px;
62 | }
63 | }
64 |
65 | .delete-button .lid {
66 | position: absolute;
67 | top: 24px;
68 | left: 50%;
69 | translate: -50% 0;
70 | transform-origin: 0% 0%;
71 | width: 24px;
72 | height: 2px;
73 | background: #ffffff;
74 | }
75 |
76 | @keyframes balls-drop {
77 | 0%,
78 | 20% {
79 | translate: -50% 0;
80 | }
81 | 40% {
82 | scale: 1 1;
83 | }
84 | 40%,
85 | 100% {
86 | translate: -50% 72px;
87 | }
88 |
89 | 50%,
90 | 100% {
91 | scale: 2.1 1;
92 | }
93 | }
94 |
95 | .delete-button .balls {
96 | position: absolute;
97 | top: -32px;
98 | left: 50%;
99 | translate: -50% 0;
100 | width: 9px;
101 | height: 9px;
102 | border-radius: 50%;
103 | background: #ffffff;
104 | }
105 |
106 | @keyframes fill {
107 | 0%,
108 | 20% {
109 | translate: 0 0;
110 | }
111 | 50%,
112 | 70% {
113 | translate: 0 -50%;
114 | }
115 | 90%,
116 | 100% {
117 | translate: 0 -100%;
118 | }
119 | }
120 |
121 | .delete-button .filler {
122 | position: absolute;
123 | top: 100%;
124 | left: 50%;
125 | margin-left: -32px;
126 | width: 64px;
127 | height: 120%;
128 | background: #ffffff;
129 | }
130 |
131 | .delete-button:disabled {
132 | cursor: not-allowed;
133 | }
134 |
135 | .delete-button.deleting .balls {
136 | animation: balls-drop 2 linear 1.25s;
137 | }
138 |
139 | .delete-button.deleting .filler {
140 | animation: fill 2.5s both;
141 | }
142 |
143 | .delete-button.deleting .lid {
144 | animation: lid-open 2.5s both;
145 | }
146 |
--------------------------------------------------------------------------------
/src/components/buttons/FabButton/FabButton.css:
--------------------------------------------------------------------------------
1 | .page.fab-button-page {
2 | background: #16151b;
3 | }
4 |
5 | .fab {
6 | position: fixed;
7 | right: 30px;
8 | bottom: 38px;
9 | border-radius: 50%;
10 | box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
11 | }
12 |
13 | .fab button {
14 | cursor: pointer;
15 | border: 0;
16 | background: transparent;
17 | }
18 |
19 | .fab > button {
20 | position: relative;
21 | z-index: 1;
22 | display: grid;
23 | place-items: center;
24 | width: 64px;
25 | height: 64px;
26 | border-radius: 50%;
27 | border: 0;
28 | background: #e952de;
29 | border: 0;
30 | color: #f9f9f9;
31 | transition: 0.2s;
32 | rotate: 0deg;
33 | }
34 |
35 | .fab > button > span {
36 | font-size: 36px;
37 | }
38 |
39 | .fab-menu {
40 | position: absolute;
41 | z-index: 0;
42 | top: 50%;
43 | left: 50%;
44 | width: 360px;
45 | height: 360px;
46 | translate: -50% -50%;
47 | border: 80px solid #282633;
48 | border-radius: 50%;
49 | rotate: -220deg;
50 | scale: 0.7;
51 | opacity: 0;
52 | transition: 0.4s ease-out;
53 | }
54 |
55 | .fab.open > button {
56 | rotate: 45deg;
57 | }
58 |
59 | .fab.open .fab-menu {
60 | rotate: 0deg;
61 | scale: 1;
62 | opacity: 1;
63 | }
64 |
65 | .fab-menu > button {
66 | position: absolute;
67 | color: #e0e0e0;
68 | transition: 0.4s;
69 | }
70 |
71 | .fab-menu > button:hover {
72 | scale: 1.2;
73 | color: #f9f9f9;
74 | }
75 |
76 | .fab .material-symbols-outlined {
77 | font-size: 36px;
78 | }
79 |
80 | .fab-menu > button:nth-child(1) {
81 | left: 78px;
82 | top: -58px;
83 | }
84 |
85 | .fab-menu > button:nth-child(2) {
86 | left: -16px;
87 | top: -16px;
88 | }
89 |
90 | .fab-menu > button:nth-child(3) {
91 | left: -58px;
92 | top: 78px;
93 | }
94 |
--------------------------------------------------------------------------------
/src/components/buttons/FabButton/FabButton.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./FabButton.css";
3 |
4 | const Icon = ({ children }) => (
5 | {children}
6 | );
7 |
8 | export const FabButton = () => {
9 | const [isOpen, setIsOpen] = useState(false);
10 |
11 | return (
12 |
13 |
14 |
setIsOpen(!isOpen)}>
15 | add
16 |
17 |
18 |
19 | favorite
20 |
21 |
22 | sell
23 |
24 |
25 | settings
26 |
27 |
28 |
29 |
30 | );
31 | };
32 |
--------------------------------------------------------------------------------
/src/components/buttons/TrashButton/TrashButton.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./TrashButton.css";
3 | import paper from "./paper.svg";
4 | import shredded from "./shredded.svg";
5 |
6 | export const TrashButton = () => {
7 | const [isDeleting, setIsDeleting] = useState(false);
8 |
9 | const handleClick = () => {
10 | setIsDeleting(true);
11 | // do something async
12 | setTimeout(() => {
13 | setIsDeleting(false);
14 | }, 2500);
15 | };
16 |
17 | return (
18 |
19 |
24 |
25 | Delete
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | );
41 | };
42 |
--------------------------------------------------------------------------------
/src/components/buttons/TrashButton/paper.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/components/buttons/TrashButton/shredded.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/components/buttons/index.js:
--------------------------------------------------------------------------------
1 | export * from "./DeleteButton/DeleteButton";
2 | export * from "./TrashButton/TrashButton";
3 | export * from "./FabButton/FabButton";
4 |
--------------------------------------------------------------------------------
/src/components/cards/Card1/Card1.jsx:
--------------------------------------------------------------------------------
1 | import "./styles.css";
2 |
3 | const cards = [
4 | {
5 | name: "summary",
6 | total: 21,
7 | description: "Due Tasks",
8 | footer: "Completed: 13",
9 | more: "More Information",
10 | },
11 | {
12 | name: "overdue",
13 | total: 17,
14 | description: "Projects",
15 | footer: "Yesterday: 9",
16 | more: "More Information",
17 | },
18 | {
19 | name: "features",
20 | total: 38,
21 | description: "Proposals",
22 | footer: "Implemented: 6",
23 | more: "More Information",
24 | },
25 | ];
26 |
27 | export const Card1 = () => {
28 | return (
29 |
30 |
31 | {cards.map((card) => (
32 |
33 |
34 |
35 |
36 |
37 | {card.name}
38 | more_vert
39 |
40 | {card.total}
41 |
{card.description}
42 | {card.footer}
43 |
44 |
45 |
46 | {card.name}
47 | close
48 |
49 |
More Information
50 |
51 |
52 |
53 | ))}
54 |
55 |
56 | );
57 | };
58 |
--------------------------------------------------------------------------------
/src/components/cards/Card1/styles.css:
--------------------------------------------------------------------------------
1 | .page.card-1-page {
2 | margin: 0;
3 | height: 100vh;
4 | display: grid;
5 | place-items: center;
6 | color: #f7f7f7;
7 | background: #121212;
8 | font-family: "Euclid Circular A", "Poppins";
9 | }
10 |
11 | .card-1-page h2,
12 | .card-1-page h3,
13 | .card-1-page h4 {
14 | margin: 0;
15 | font-weight: 500;
16 | }
17 |
18 | .card-1-page .cards {
19 | display: flex;
20 | gap: 30px;
21 | }
22 |
23 | .card-1-page .card {
24 | position: relative;
25 | perspective: 1000px;
26 | width: 300px;
27 | height: 300px;
28 | }
29 |
30 | .card-1-page .card header {
31 | display: flex;
32 | justify-content: space-between;
33 | align-items: center;
34 | height: 40px;
35 | margin-bottom: 26px;
36 | }
37 |
38 | .card-1-page .card header h2 {
39 | font-size: 20px;
40 | text-transform: capitalize;
41 | }
42 |
43 | .card-1-page .card .front,
44 | .card-1-page .card .back {
45 | position: absolute;
46 | top: 0;
47 | left: 0;
48 | right: 0;
49 | bottom: 0;
50 | backface-visibility: hidden;
51 | background: #1e1e1e;
52 | border-radius: 10px;
53 | padding: 36px 36px 44px 44px;
54 | transition: 0.6s;
55 | cursor: pointer;
56 | }
57 |
58 | .card-1-page .back {
59 | transform: rotateY(180deg);
60 | }
61 |
62 | .card-1-page input {
63 | position: absolute;
64 | scale: 0;
65 | }
66 |
67 | .card-1-page input:checked ~ .card .back {
68 | transform: rotateY(0);
69 | }
70 |
71 | .card-1-page input:checked ~ .card .front {
72 | transform: rotateY(-180deg);
73 | }
74 |
75 | .card-1-page .card var {
76 | font-style: normal;
77 | font-size: 80px;
78 | line-height: 1;
79 | }
80 |
81 | .card-1-page .card h3 {
82 | margin: 0 0 30px;
83 | font-weight: 500;
84 | }
85 |
86 | .card-1-page #summary :is(var, h3) {
87 | color: #3b82f6;
88 | }
89 |
90 | .card-1-page #overdue :is(var, h3) {
91 | color: #e56363;
92 | }
93 |
94 | .card-1-page #features :is(var, h3) {
95 | color: #25b697;
96 | }
97 |
98 | .card-1-page .card :is(h4, p) {
99 | opacity: 0.6;
100 | font-size: 20px;
101 | }
102 |
103 | .card-1-page .card p {
104 | margin-top: 76px;
105 | }
106 |
--------------------------------------------------------------------------------
/src/components/cards/Card2/Card2.css:
--------------------------------------------------------------------------------
1 | .page.card-2-example-page {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | margin: 0;
6 | height: 100vh;
7 | background: linear-gradient(45deg, #0cd2d1, #0857c0);
8 | color: #fdfcfd;
9 | font-family: "Euclid Circular A", "Poppins";
10 | }
11 |
12 | .card-2 {
13 | display: flex;
14 | align-items: center;
15 | width: 75vw;
16 | max-width: 650px;
17 | padding: 50px 30px 50px 20px;
18 | background: #121017;
19 | border-radius: 24px;
20 | box-shadow: 0 80px 60px rgb(0 0 0 / 12%);
21 | }
22 |
23 | .card-2 img {
24 | max-width: 280px;
25 | width: 32vw;
26 | height: 300px;
27 | object-fit: cover;
28 | margin-left: -60px;
29 | margin-right: 30px;
30 | border-radius: inherit;
31 | box-shadow: 0 60px 40px rgb(0 0 0 / 12%);
32 | transition: border-radius 0.3s;
33 | }
34 |
35 | .card-2 h2 {
36 | font-size: 26px;
37 | font-weight: 400;
38 | margin-top: 0;
39 | margin-right: 30px;
40 | margin-bottom: 6px;
41 | }
42 |
43 | .card-2 h3 {
44 | font-size: 16px;
45 | font-weight: 400;
46 | margin: 0 0 12px;
47 | opacity: 0.66;
48 | }
49 |
50 | .card-2 p {
51 | font-size: 14px;
52 | font-weight: 400;
53 | margin-bottom: 30px;
54 | opacity: 0.42;
55 | }
56 |
57 | .card-2 .buttons {
58 | display: flex;
59 | gap: 12px;
60 | }
61 |
62 | .card-2 button {
63 | border: 1px solid #f8f8f8;
64 | background: transparent;
65 | color: #f8f8f8;
66 | width: 40%;
67 | min-width: 100px;
68 | text-align: center;
69 | font-family: inherit;
70 | padding: 12px 26px;
71 | font-size: 16px;
72 | border-radius: 40px;
73 | }
74 |
75 | .card-2 button.primary {
76 | background: #ffffff;
77 | color: #121017;
78 | }
79 |
80 | @media (width <= 600px) {
81 | .card-2 {
82 | margin: 0 40px;
83 | padding-left: 50px;
84 | padding-right: 50px;
85 | padding-bottom: 60px;
86 | width: 100%;
87 | text-align: center;
88 | flex-direction: column;
89 | }
90 |
91 | .card-2 .buttons {
92 | justify-content: center;
93 | }
94 |
95 | .card-2 .buttons button {
96 | width: 50%;
97 | }
98 |
99 | .card-2 h2 {
100 | margin-right: 0;
101 | font-size: 26px;
102 | }
103 |
104 | .card-2 img {
105 | margin: -100px 0 30px 0;
106 | width: 100%;
107 | max-width: 1000px;
108 | height: 250px;
109 | }
110 |
111 | .card-2 p {
112 | max-width: 400px;
113 | }
114 | }
115 |
116 | @media (width <= 420px) {
117 | .card-2 img {
118 | height: 50vw;
119 | width: 50vw;
120 | border-radius: 50%;
121 | margin: -140px 0 30px 0;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/components/cards/Card2/Card2.jsx:
--------------------------------------------------------------------------------
1 | import "./Card2.css";
2 |
3 | export const Card2 = ({
4 | image,
5 | title,
6 | subtitle,
7 | description,
8 | onProfile,
9 | onFollow,
10 | }) => (
11 |
12 |
13 |
14 |
{title}
15 |
{subtitle}
16 |
{description}
17 |
18 | Profile
19 |
20 | Follow
21 |
22 |
23 |
24 |
25 | );
26 |
--------------------------------------------------------------------------------
/src/components/cards/Card2/Card2Example.jsx:
--------------------------------------------------------------------------------
1 | import { Card2 } from "./Card2";
2 | import image from "./image.jpg";
3 |
4 | export const Card2Example = () => {
5 | const handleProfile = () => {
6 | // goto profile
7 | };
8 |
9 | const handleFollow = () => {
10 | // follow account
11 | };
12 |
13 | return (
14 |
24 | );
25 | };
26 |
--------------------------------------------------------------------------------
/src/components/cards/Card2/image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/cards/Card2/image.jpg
--------------------------------------------------------------------------------
/src/components/cards/Card3/Card3.css:
--------------------------------------------------------------------------------
1 | .card-3 {
2 | --color-primary: #356aff;
3 | --color-muted: #9895a2;
4 | --color-highlight: #242328;
5 | --border: 1px solid #2f2e32;
6 | position: relative;
7 | border-radius: 24px;
8 | width: clamp(200px, 80vw, 500px);
9 | padding-top: 30px;
10 | background: #1c1b20;
11 | }
12 |
13 | .card-3 > img {
14 | position: absolute;
15 | top: 0;
16 | left: 50%;
17 | translate: -50% -50%;
18 | width: 92px;
19 | aspect-ratio: 1/1;
20 | border-radius: 50%;
21 | background: var(--color-highlight);
22 | padding: 20px;
23 | box-shadow: 0 20px 150px rgb(0 0 0 / 8%);
24 | }
25 |
26 | .card-3 .main {
27 | padding: 24px 24px 0;
28 | display: flex;
29 | flex-direction: column;
30 | justify-content: center;
31 | text-align: center;
32 | }
33 |
34 | .card-3 :is(h2, h3, h4, h5) {
35 | font-weight: 400;
36 | margin: 0;
37 | }
38 |
39 | .card-3 em {
40 | font-style: normal;
41 | color: var(--color-primary);
42 | }
43 |
44 | .card-3 h2 {
45 | font-weight: 600;
46 | font-size: 20px;
47 | margin-top: 18px;
48 | margin-bottom: 18px;
49 | }
50 |
51 | .card-3 h3 {
52 | font-weight: 300;
53 | font-size: clamp(16px, 4vw, 20px);
54 | color: var(--color-muted);
55 | }
56 |
57 | .card-3 h4 {
58 | font-weight: 500;
59 | font-size: clamp(22px, 5.5vw, 26px);
60 | margin-bottom: 6px;
61 | }
62 |
63 | .card-3 h5 {
64 | color: var(--color-muted);
65 | font-size: clamp(14px, 4vw, 16px);
66 | margin-bottom: 40px;
67 | }
68 |
69 | .card-3 .details {
70 | display: flex;
71 | align-items: center;
72 | justify-content: space-between;
73 | padding: 0 24px;
74 | margin-bottom: 20px;
75 | font-size: clamp(14px, 4vw, 16px);
76 | }
77 |
78 | .card-3 .salary em {
79 | color: var(--color-muted);
80 | }
81 |
82 | .card-3 .date {
83 | color: var(--color-muted);
84 | }
85 |
86 | .card-3 .footer {
87 | display: flex;
88 | align-items: center;
89 | justify-content: space-between;
90 | gap: 8px;
91 | padding: 16px 24px;
92 | border-top: var(--border);
93 | }
94 |
95 | .card-3 .footer button {
96 | background: transparent;
97 | border: var(--border);
98 | width: 40px;
99 | height: 40px;
100 | border-radius: 50%;
101 | display: grid;
102 | place-items: center;
103 | color: inherit;
104 | }
105 |
106 | .card-3 .footer button span {
107 | font-size: 22px;
108 | }
109 |
110 | .card-3 .badge {
111 | display: inline-flex;
112 | margin-right: auto;
113 | align-items: center;
114 | gap: 12px;
115 | padding-right: 20px;
116 | font-size: 14px;
117 | border-radius: 50px;
118 | background: var(--color-highlight);
119 | }
120 |
121 | .card-3 .badge .text {
122 | display: none;
123 | }
124 |
125 | .card-3 .badge img {
126 | width: 40px;
127 | }
128 |
129 | .card-3 .badge p {
130 | color: var(--color-muted);
131 | }
132 |
133 | @media (width >= 430px) {
134 | .card-3 {
135 | padding-top: 0;
136 | }
137 |
138 | .card-3 > img {
139 | position: absolute;
140 | top: 20px;
141 | right: 20px;
142 | left: auto;
143 | translate: 0;
144 | width: clamp(68px, 12vw, 80px);
145 | padding: 16px;
146 | border-color: transparent;
147 | box-shadow: none;
148 | }
149 |
150 | .card-3 .main {
151 | text-align: left;
152 | }
153 |
154 | .card-3 .badge .text {
155 | display: inline;
156 | }
157 |
158 | .card-3 h5 {
159 | margin-bottom: 28px;
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/src/components/cards/Card3/Card3.jsx:
--------------------------------------------------------------------------------
1 | import logo from "./logo.svg";
2 | import avatar from "./avatar.png";
3 | import "./Card3.css";
4 |
5 | export const Card3 = ({
6 | company,
7 | level,
8 | role,
9 | location,
10 | isRemote,
11 | salary,
12 | when,
13 | profileMatch,
14 | onShare,
15 | onSave,
16 | }) => (
17 |
18 |
19 |
20 |
{company}
21 | {level}
22 | {role}
23 |
24 | {location} {isRemote && (Remote) }
25 |
26 |
27 |
28 |
29 | {" "}
30 | {salary}
31 | /month {" "}
32 |
33 | {when}
34 |
35 |
50 |
51 | );
52 |
--------------------------------------------------------------------------------
/src/components/cards/Card3/Card3Example.css:
--------------------------------------------------------------------------------
1 | .page.card-3-page {
2 | background: #111116;
3 | color: #ffffff;
4 | height: 100vh;
5 | margin: 0;
6 | display: grid;
7 | place-items: center;
8 | font-family: "Euclid Circular B", "Poppins";
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/cards/Card3/Card3Example.jsx:
--------------------------------------------------------------------------------
1 | import { Card3 } from "./Card3";
2 | import "./Card3Example.css";
3 |
4 | export const Card3Example = () => {
5 | const onShare = () => console.log("share");
6 | const onSave = () => console.log("share");
7 |
8 | return (
9 |
23 | );
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/cards/Card3/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/cards/Card3/avatar.png
--------------------------------------------------------------------------------
/src/components/cards/Card3/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Google-color
6 | Created with Sketch.
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/components/cards/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Card1/Card1";
2 | export * from "./Card2/Card2Example";
3 | export * from "./Card3/Card3Example";
4 |
--------------------------------------------------------------------------------
/src/components/carousels/Carousel1/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel1/1.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel1/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel1/2.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel1/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel1/3.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel1/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel1/4.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel1/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel1/5.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel1/Carousel1.jsx:
--------------------------------------------------------------------------------
1 | import { Swiper, SwiperSlide } from "swiper/react";
2 | import { EffectCoverflow, Pagination } from "swiper/modules";
3 | import "./styles.css";
4 | import "swiper/css";
5 | import "swiper/css/navigation";
6 | import "swiper/css/pagination";
7 |
8 | import image1 from "./1.jpg";
9 | import image2 from "./2.jpg";
10 | import image3 from "./3.jpg";
11 | import image4 from "./4.jpg";
12 | import image5 from "./5.jpg";
13 |
14 | const slides = [
15 | {
16 | title: "1 Series",
17 | image: image1,
18 | },
19 | {
20 | title: "2 Series",
21 | image: image2,
22 | },
23 | {
24 | title: "3 Series",
25 | image: image3,
26 | },
27 | {
28 | title: "4 Series",
29 | image: image4,
30 | },
31 | {
32 | title: "5 Series",
33 | image: image5,
34 | },
35 | ];
36 |
37 | export const Carousel1 = () => {
38 | return (
39 |
40 |
56 | {slides.map((slide) => (
57 |
63 |
64 |
65 |
{slide.title}
66 |
explore
67 |
68 |
69 |
70 | ))}
71 |
72 |
73 | );
74 | };
75 |
--------------------------------------------------------------------------------
/src/components/carousels/Carousel1/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | }
6 |
7 | .page.carousel-1-page {
8 | position: relative;
9 | display: flex;
10 | align-items: center;
11 | gap: 50px;
12 | padding: 0 8vw;
13 | background: linear-gradient(45deg, #2c3d46, #0c0f13);
14 | color: #f9f9f9;
15 | }
16 |
17 | .swiper a {
18 | display: inline-block;
19 | text-decoration: none;
20 | text-transform: uppercase;
21 | color: #717171;
22 | font-weight: 500;
23 | background: #fff;
24 | border-radius: 3.125rem;
25 | margin: 0 auto;
26 | padding: 10px 26px;
27 | font-size: 0.9rem;
28 | transition: 0.3s ease-in-out;
29 | }
30 |
31 | .swiper {
32 | width: 100%;
33 | max-width: 800px;
34 | height: 440px;
35 | }
36 |
37 | .swiper-slide {
38 | overflow: hidden;
39 | display: flex;
40 | flex-direction: column;
41 | justify-content: end;
42 | align-items: center;
43 | filter: grayscale(0.6);
44 | background-size: cover;
45 | background-position: center;
46 | }
47 |
48 | .swiper-slide h2 {
49 | color: #fff;
50 | font-weight: 100;
51 | font-size: 20px;
52 | line-height: 1.4;
53 | margin-bottom: 0.625rem;
54 | text-transform: uppercase;
55 | letter-spacing: 1px;
56 | text-align: center;
57 | }
58 |
59 | .swiper-slide a:hover {
60 | color: #005baa;
61 | }
62 |
63 | .swiper-slide div {
64 | position: absolute;
65 | z-index: 1;
66 | inset: 0;
67 | background: linear-gradient(rgb(0 0 0 / 0%) 55%, rgb(0 0 0 / 80%));
68 | transition: 0.25s;
69 | opacity: 0;
70 | align-self: stretch;
71 | padding-bottom: 70px;
72 | height: 100%;
73 | display: flex;
74 | align-items: center;
75 | flex-direction: column;
76 | justify-content: flex-end;
77 | }
78 |
79 | .swiper-slide-active div {
80 | opacity: 1;
81 | }
82 |
83 | .swiper-slide > div > div {
84 | translate: 0 100px;
85 | transition: 0.3s;
86 | }
87 |
88 | .swiper-slide-active > div > div {
89 | translate: 0;
90 | }
91 |
92 | .swiper-pagination-bullet,
93 | .swiper-pagination-bullet-active {
94 | background: #fff !important;
95 | }
96 |
97 | .swiper-pagination {
98 | bottom: 10px !important;
99 | transform: scale(1.3);
100 | }
101 |
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/1.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/2.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/3.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/4.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/5.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/6.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/7.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/8.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/carousels/Carousel2/9.jpg
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/Carousel2.jsx:
--------------------------------------------------------------------------------
1 | import { Swiper, SwiperSlide } from "swiper/react";
2 | import { EffectCoverflow } from "swiper/modules";
3 |
4 | import "swiper/css";
5 | import "swiper/css/effect-coverflow";
6 | import "./styles.css";
7 |
8 | import image1 from "./1.jpg";
9 | import image2 from "./2.jpg";
10 | import image3 from "./3.jpg";
11 | import image4 from "./4.jpg";
12 | import image5 from "./5.jpg";
13 | import image6 from "./6.jpg";
14 | import image7 from "./7.jpg";
15 | import image8 from "./8.jpg";
16 | import image9 from "./9.jpg";
17 |
18 | const slides = [image2, image3, image4, image5, image6, image7, image8, image9];
19 |
20 | export const Carousel2 = () => {
21 | return (
22 |
23 |
38 |
39 | {slides.map((slide) => (
40 |
46 | ))}
47 |
48 |
49 |
50 |
51 | );
52 | };
53 |
--------------------------------------------------------------------------------
/src/components/carousels/Carousel2/styles.css:
--------------------------------------------------------------------------------
1 | .page.carousel-2-page {
2 | background: #010101;
3 | font-size: 14px;
4 | color: #010101;
5 | margin: 0;
6 | padding: 0;
7 | height: 100vh;
8 | width: 100vw;
9 | display: flex;
10 | justify-content: center;
11 | align-items: center;
12 | }
13 |
14 | .swiper {
15 | padding-top: 50px;
16 | padding-bottom: 140px;
17 | }
18 |
19 | .swiper .swiper-slide {
20 | background-position: center;
21 | background-size: cover;
22 | border-radius: 10px;
23 | width: 300px;
24 | height: 250px;
25 | filter: saturate(1.2);
26 | -webkit-box-reflect: below 1px
27 | linear-gradient(transparent, transparent, #0006);
28 | }
29 |
--------------------------------------------------------------------------------
/src/components/carousels/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Carousel1/Carousel1";
2 | export * from "./Carousel2/Carousel2";
3 |
--------------------------------------------------------------------------------
/src/components/controls/AutoSuggest/styles.css:
--------------------------------------------------------------------------------
1 | .page.auto-suggest-page {
2 | background: #18181b;
3 | display: flex;
4 | flex-direction: column;
5 | justify-content: center;
6 | align-items: center;
7 | gap: 50px;
8 | padding-top: 0;
9 | }
10 |
11 | .auto-suggest-page img {
12 | width: 240px;
13 | margin: 0 auto;
14 | }
15 |
16 | .auto-suggest-page button {
17 | padding: 10px 16px;
18 | border-radius: 4px;
19 | border: 0;
20 | background: #303134;
21 | color: inherit;
22 | font-family: inherit;
23 | }
24 |
25 | .auto-suggest-page p {
26 | margin: 0;
27 | font-size: 13px;
28 | }
29 |
30 | .auto-suggest-page p a {
31 | color: #8ab4f7;
32 | }
33 |
34 | .auto-suggest {
35 | position: relative;
36 | }
37 |
38 | .auto-suggest input {
39 | width: 440px;
40 | height: 44px;
41 | padding: 0 20px 0 44px;
42 | border-radius: 22px;
43 | border: 1px solid #5f6367;
44 | background: transparent;
45 | color: #e8eaed;
46 | font-size: 16px;
47 | font-family: inherit;
48 | outline: none;
49 | }
50 |
51 | .auto-suggest input:focus {
52 | background: #2c2e34;
53 | border-color: #2c2e34;
54 | border-bottom-right-radius: 0;
55 | border-bottom-left-radius: 0;
56 | }
57 |
58 | .auto-suggest span:nth-child(1) {
59 | position: absolute;
60 | top: 50%;
61 | left: 14px;
62 | translate: 0 -50%;
63 | }
64 |
65 | .auto-suggest-buttons {
66 | display: flex;
67 | gap: 16px;
68 | }
69 |
70 | .auto-suggest .menu {
71 | display: none;
72 | position: absolute;
73 | z-index: 1;
74 | overflow: hidden;
75 | top: 44px;
76 | left: 0;
77 | width: 100%;
78 | max-height: 228px;
79 | padding: 0 16px 6px;
80 | background: #2c2e34;
81 | border-bottom-right-radius: 22px;
82 | border-bottom-left-radius: 22px;
83 | }
84 |
85 | .auto-suggest input:focus ~ .menu,
86 | .auto-suggest .menu:hover {
87 | display: block;
88 | }
89 |
90 | .auto-suggest .menu > div {
91 | padding: 8px 0;
92 | border-top: 1px solid #5f6367;
93 | line-height: 1.8;
94 | }
95 |
96 | .auto-suggest .menu > div button {
97 | display: block;
98 | background: transparent;
99 | padding: 0;
100 | height: 30px;
101 | font-size: 16px;
102 | cursor: pointer;
103 | width: 100%;
104 | text-align: left;
105 | }
106 |
--------------------------------------------------------------------------------
/src/components/controls/EditableText/EditableText.css:
--------------------------------------------------------------------------------
1 | .editable-text {
2 | display: flex;
3 | align-items: center;
4 | gap: 8px;
5 | }
6 |
7 | .editable-text-value.is-editing ~ .editable-text-buttons {
8 | opacity: 1;
9 | visibility: visible;
10 | }
11 |
12 | .editable-text-buttons {
13 | display: flex;
14 | gap: 2px;
15 | opacity: 0;
16 | visibility: hidden;
17 | transition: 0.3s;
18 | }
19 |
20 | .editable-text:hover .editable-text-buttons {
21 | opacity: 1;
22 | visibility: visible;
23 | }
24 |
25 | .editable-text-buttons button {
26 | cursor: pointer;
27 | background: transparent;
28 | border: 0;
29 | display: grid;
30 | place-items: center;
31 | color: inherit;
32 | opacity: 0.5;
33 | transition: 0.3s;
34 | }
35 |
36 | .editable-text-buttons button:hover {
37 | opacity: 0.8;
38 | }
39 |
40 | .editable-text-value {
41 | outline: none;
42 | }
43 |
--------------------------------------------------------------------------------
/src/components/controls/EditableText/EditableText.jsx:
--------------------------------------------------------------------------------
1 | import { useLayoutEffect, useRef, useState } from "react";
2 | import "./EditableText.css";
3 |
4 | const setCaret = (el) => {
5 | if (!el) return;
6 | try {
7 | const range = document.createRange();
8 | const sel = window.getSelection();
9 | range.setStart(el.childNodes[0], el.innerText.length);
10 | range.collapse(true);
11 | sel.removeAllRanges();
12 | sel.addRange(range);
13 | } catch (err) {
14 | console.log("Error Setting Caret: ", err);
15 | }
16 | };
17 |
18 | const IconButton = ({ children, onClick }) => (
19 |
20 | {children}
21 |
22 | );
23 |
24 | export const EditableText = ({ name, defaultValue, onSave, className }) => {
25 | const [isEditing, setIsEditing] = useState(false);
26 |
27 | const nextValue = useRef("");
28 |
29 | const spanRef = useRef(null);
30 |
31 | const handleChange = (e) => (nextValue.current = e.target.innerText);
32 |
33 | const handleSave = () => {
34 | toggleIsEditing();
35 | onSave(name, nextValue.current);
36 | };
37 |
38 | const toggleIsEditing = () => setIsEditing(!isEditing);
39 |
40 | useLayoutEffect(() => {
41 | if (isEditing) {
42 | spanRef.current.focus();
43 | setCaret(spanRef.current);
44 | } else {
45 | spanRef.current.innerText = defaultValue;
46 | nextValue.current = defaultValue;
47 | }
48 | }, [isEditing]);
49 |
50 | return (
51 |
52 |
61 | {defaultValue}
62 |
63 |
64 | {isEditing ? (
65 | <>
66 | check_circle
67 | cancel
68 | >
69 | ) : (
70 | edit
71 | )}
72 |
73 |
74 | );
75 | };
76 |
--------------------------------------------------------------------------------
/src/components/controls/EditableText/EditableTextExample.css:
--------------------------------------------------------------------------------
1 | .page.editable-text-page {
2 | --gradient: linear-gradient(45deg, #ff7c7d, #ffda67);
3 | --card: #272524;
4 | display: flex;
5 | align-items: center;
6 | justify-content: center;
7 | margin: 0;
8 | height: 100vh;
9 | background: var(--gradient);
10 | color: #fdfcfd;
11 | font-family: "Euclid Circular B", "Poppins";
12 | }
13 |
14 | .editable-text-card {
15 | display: flex;
16 | align-items: center;
17 | width: 75vw;
18 | max-width: 650px;
19 | padding: 44px 30px 44px 20px;
20 | background: var(--card);
21 | border-radius: 24px;
22 | }
23 |
24 | .editable-text-card img {
25 | max-width: 280px;
26 | width: 36vw;
27 | height: 300px;
28 | object-fit: cover;
29 | margin-left: -60px;
30 | margin-right: 30px;
31 | border-radius: inherit;
32 | box-shadow: 0 60px 40px rgb(0 0 0 / 8%);
33 | transition: border-radius 0.3s;
34 | }
35 |
36 | .editable-text-card-title {
37 | display: block;
38 | font-size: 24px;
39 | font-weight: 400;
40 | margin-top: 0;
41 | margin-bottom: 10px;
42 | }
43 |
44 | .editable-text-card-role {
45 | display: block;
46 | font-size: 16px;
47 | font-weight: 400;
48 | margin: 0 0 5px;
49 | opacity: 0.75;
50 | }
51 |
52 | .editable-text-card p {
53 | font-size: 14px;
54 | font-weight: 400;
55 | margin-bottom: 30px;
56 | opacity: 0.5;
57 | }
58 |
59 | .editable-text-socials {
60 | display: flex;
61 | align-items: center;
62 | gap: 8px;
63 | }
64 |
65 | .editable-text-socials > button {
66 | position: relative;
67 | border: 0;
68 | background: transparent;
69 | color: #f8f8f8;
70 | padding: 0;
71 | }
72 |
73 | .editable-text-socials > button:first-child::before {
74 | content: "";
75 | position: absolute;
76 | z-index: 0;
77 | top: 50%;
78 | left: 50%;
79 | width: 52px;
80 | height: 52px;
81 | translate: -50% -50%;
82 | border-radius: 50%;
83 | border: 2px solid #ff7c7d;
84 | transition: 0.3s;
85 | transform: translateY(0);
86 | }
87 |
88 | .editable-text-socials > button > i {
89 | position: relative;
90 | z-index: 1;
91 | border: 4px solid var(--card);
92 | background: rgb(255 255 255 / 12%);
93 | display: grid;
94 | place-items: center;
95 | font-size: 24px;
96 | width: 50px;
97 | height: 50px;
98 | border-radius: 40px;
99 | }
100 |
101 | @media (width <= 600px) {
102 | .editable-text-card {
103 | margin: 0 40px;
104 | padding-left: 50px;
105 | padding-right: 50px;
106 | padding-bottom: 60px;
107 | width: 100%;
108 | text-align: center;
109 | flex-direction: column;
110 | }
111 |
112 | .editable-text-card h2 {
113 | margin-right: 0;
114 | font-size: 26px;
115 | }
116 |
117 | .editable-text-card img {
118 | margin: -100px 0 30px 0;
119 | width: 100%;
120 | max-width: 1000px;
121 | height: 250px;
122 | }
123 |
124 | .editable-text-card p {
125 | max-width: 360px;
126 | }
127 |
128 | .editable-text-socials {
129 | justify-content: center;
130 | }
131 | }
132 |
133 | @media (width <= 440px) {
134 | .editable-text-card img {
135 | height: 50vw;
136 | width: 50vw;
137 | border-radius: 50%;
138 | border: 12px solid var(--card);
139 | box-shadow: none;
140 | margin: -140px 0 30px 0;
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/src/components/controls/EditableText/EditableTextExample.jsx:
--------------------------------------------------------------------------------
1 | import image from "./image.jpg";
2 | import "./EditableTextExample.css";
3 | import { EditableText } from "./EditableText";
4 | import { useState } from "react";
5 |
6 | export const EditableTitleExample = () => {
7 | const [state, setState] = useState({
8 | title: "Jill Scott",
9 | role: "Frontend Engineer",
10 | });
11 |
12 | const { title, role } = state;
13 |
14 | const handleSave = (name, value) =>
15 | setState({
16 | ...state,
17 | [name]: value,
18 | });
19 |
20 | return (
21 |
22 |
23 |
24 |
25 |
31 |
37 |
38 | Transforming ideas into realities, creating interfaces that inspire
39 | and engage users dreams.
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | );
56 | };
57 |
--------------------------------------------------------------------------------
/src/components/controls/EditableText/image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/controls/EditableText/image.jpg
--------------------------------------------------------------------------------
/src/components/controls/PasswordStrength/PasswordStrength.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import logo from "./logo.svg";
3 | import "./styles.css";
4 |
5 | const strengthLabels = ["weak", "medium", "medium", "strong"];
6 |
7 | export const PasswordStrength = ({ placeholder, onChange }) => {
8 | const [strength, setStrength] = useState("");
9 |
10 | const getStrength = (password) => {
11 | let strengthIndicator = -1;
12 |
13 | if (/[a-z]/.test(password)) strengthIndicator++;
14 | if (/[A-Z]/.test(password)) strengthIndicator++;
15 | if (/\d/.test(password)) strengthIndicator++;
16 | if (/[^a-zA-Z0-9]/.test(password)) strengthIndicator++;
17 |
18 | if (password.length >= 16) strengthIndicator++;
19 |
20 | return strengthLabels[strengthIndicator];
21 | };
22 |
23 | const handleChange = (event) => {
24 | setStrength(getStrength(event.target.value));
25 | onChange(event.target.value);
26 | };
27 |
28 | return (
29 | <>
30 |
38 |
41 | {strength && `${strength} password`}
42 | >
43 | );
44 | };
45 |
46 | export const PasswordStrengthExample = () => {
47 | const handleChange = (value) => console.log(value);
48 |
49 | return (
50 |
51 |
52 |
53 |
Sign Up
54 |
71 |
72 |
73 | );
74 | };
75 |
--------------------------------------------------------------------------------
/src/components/controls/PasswordStrength/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | .page {
6 | display: grid;
7 | place-items: center;
8 | margin: 0;
9 | background: #000000;
10 | font-family: "Euclid Circular A", "Poppins";
11 | color: #fdfdfd;
12 | }
13 |
14 | .login-card {
15 | width: 400px;
16 | padding: 60px 30px 30px;
17 | border-radius: 16px;
18 | background: #0e0d0d;
19 | text-align: center;
20 | }
21 |
22 | .login-card > h2 {
23 | font-size: 36px;
24 | font-weight: 600;
25 | margin: 0 0 30px;
26 | }
27 |
28 | .login-card img {
29 | width: 260px;
30 | margin-bottom: 20px;
31 | }
32 |
33 | .login-form {
34 | width: 100%;
35 | margin: 0;
36 | display: grid;
37 | }
38 |
39 | .login-form input.control::placeholder {
40 | color: #9f9d9e;
41 | }
42 |
43 | .control {
44 | outline: none;
45 | width: 100%;
46 | height: 56px;
47 | padding: 0 16px;
48 | color: inherit;
49 | background: #181919;
50 | border: 0;
51 | border-radius: 6px;
52 | margin: 8px 0;
53 | font-family: inherit;
54 | font-size: 18px;
55 | transition: 0.4s;
56 | }
57 |
58 | button.control {
59 | cursor: pointer;
60 | width: 100%;
61 | height: 56px;
62 | padding: 0 16px;
63 | background: #0079ea;
64 | text-align: center;
65 | }
66 |
67 | .bars {
68 | margin: 8px 0;
69 | flex: 1 1 auto;
70 | display: flex;
71 | align-items: center;
72 | gap: 8px;
73 | height: 6px;
74 | border-radius: 3px;
75 | background: #181919;
76 | }
77 |
78 | .bars div {
79 | height: 6px;
80 | border-radius: 3px;
81 | transition: 0.4s;
82 | width: 0%;
83 | }
84 |
85 | .bars.weak div {
86 | background: #e24c71;
87 | width: 33.33%;
88 | }
89 |
90 | .bars.medium div {
91 | background: #f39845;
92 | width: 66.66%;
93 | }
94 |
95 | .bars.strong div {
96 | background: #57c558;
97 | width: 100%;
98 | }
99 |
100 | .strength {
101 | text-align: left;
102 | height: 30px;
103 | text-transform: capitalize;
104 | color: #868b94;
105 | }
106 |
--------------------------------------------------------------------------------
/src/components/controls/PasswordVisibility/Password.css:
--------------------------------------------------------------------------------
1 | .password-control input {
2 | --color-primary: #0088ff;
3 | --color-muted: #5a616c;
4 | border: 0;
5 | width: 100%;
6 | height: 60px;
7 | background: transparent;
8 | font-family: inherit;
9 | font-size: 16px;
10 | outline: none;
11 | }
12 |
13 | .password-visibility .password-control {
14 | position: relative;
15 | margin-bottom: 16px;
16 | }
17 |
18 | .password-control > span {
19 | position: absolute;
20 | top: 50%;
21 | translate: 0 -50%;
22 | left: 0;
23 | font-size: 22px;
24 | pointer-events: none;
25 | color: var(--color-muted);
26 | transition: 0.3s;
27 | }
28 |
29 | .password-control input {
30 | padding: 0 24px 0 36px;
31 | color: rgb(255 255 255 / 96%);
32 | height: 72px;
33 | transition: 0.3s;
34 | }
35 |
36 | .password-control :is(input:focus, input:valid) ~ label {
37 | translate: -36px -44px;
38 | scale: 0.875;
39 | }
40 |
41 | .password-control input:focus ~ label {
42 | color: var(--color-primary);
43 | }
44 |
45 | .password-control .border {
46 | position: absolute;
47 | left: 0;
48 | right: 0;
49 | bottom: 0;
50 | width: 100%;
51 | height: 2px;
52 | border-radius: 2px;
53 | background: rgb(255 255 255 / 6%);
54 | }
55 |
56 | .password-control .border::after {
57 | content: "";
58 | position: absolute;
59 | inset: 0;
60 | border-radius: inherit;
61 | background: var(--color-primary);
62 | transform: scaleX(0);
63 | opacity: 0;
64 | transition: 0.3s;
65 | }
66 |
67 | .password-control input:focus ~ .border::after {
68 | transform: scaleX(1);
69 | opacity: 1;
70 | }
71 |
72 | .password-control :is(input:focus, input:valid) ~ span {
73 | color: rgb(255 255 255 / 96%);
74 | }
75 |
76 | .password-control label {
77 | position: absolute;
78 | top: 50%;
79 | left: 30px;
80 | translate: 0 -50%;
81 | color: var(--color-muted);
82 | pointer-events: none;
83 | text-transform: capitalize;
84 | transition: 0.4s;
85 | }
86 |
87 | .password-control {
88 | margin-bottom: 20px;
89 | }
90 |
91 | .password-control input {
92 | padding-right: 50px;
93 | }
94 |
95 | .password-control button {
96 | position: absolute;
97 | top: 50%;
98 | right: 0;
99 | display: grid;
100 | place-items: center;
101 | padding: 0;
102 | height: 36px;
103 | width: 36px;
104 | translate: 0 -50%;
105 | cursor: pointer;
106 | }
107 |
108 | .password-control button span {
109 | color: var(--color-muted);
110 | transition: 0.3s;
111 | }
112 |
113 | .password-control button:hover span {
114 | color: rgb(255 255 255 / 96%);
115 | }
116 |
--------------------------------------------------------------------------------
/src/components/controls/PasswordVisibility/Password.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./Password.css";
3 |
4 | export const Icon = ({ children }) => (
5 | {children}
6 | );
7 |
8 | export const Password = ({ name, onInput }) => {
9 | const [showPassword, setShowPassword] = useState(false);
10 |
11 | const handleMouseDown = (e) => {
12 | e.preventDefault();
13 | setShowPassword(!showPassword);
14 | };
15 |
16 | const handleInput = (e) => onInput(name, e.target.value);
17 |
18 | return (
19 |
20 |
25 |
{name}
26 |
lock
27 |
28 | {showPassword ? "visibility_off" : "visibility"}
29 |
30 |
31 |
32 | );
33 | };
34 |
--------------------------------------------------------------------------------
/src/components/controls/PasswordVisibility/PasswordVisibilityExample.css:
--------------------------------------------------------------------------------
1 | .page.password-visibility-page {
2 | display: grid;
3 | place-items: center;
4 | margin: 0;
5 | padding: 0 20px;
6 | background: #3284ce;
7 | font-family: "Euclid Circular A", "Poppins";
8 | box-sizing: border-box;
9 | }
10 |
11 | .password-visibility :is(button, input) {
12 | border: 0;
13 | width: 100%;
14 | height: 60px;
15 | background: transparent;
16 | font-family: inherit;
17 | font-size: 16px;
18 | outline: none;
19 | }
20 |
21 | @keyframes clouds {
22 | 0% {
23 | scale: 1;
24 | translate: 0;
25 | }
26 | 50% {
27 | scale: 1.25;
28 | }
29 | 100% {
30 | scale: 1;
31 | translate: -100px 0;
32 | }
33 | }
34 |
35 | .password-visibility-clouds {
36 | position: fixed;
37 | top: -50vh;
38 | left: 0;
39 | height: 150vh;
40 | animation: clouds 15s both infinite alternate linear;
41 | }
42 |
43 | .password-visibility {
44 | --color-primary: #0088ff;
45 | --color-muted: #5a616c;
46 | position: fixed;
47 | display: flex;
48 | flex-direction: column;
49 | justify-content: center;
50 | z-index: 2;
51 | top: 0;
52 | left: 0;
53 | height: 100%;
54 | width: 70%;
55 | max-width: 400px;
56 | padding: 200px 60px;
57 | background: #121216;
58 | }
59 |
60 | .password-visibility > h2 {
61 | font-size: 32px;
62 | font-weight: 300;
63 | margin: 0 0 10px;
64 | color: rgb(255 255 255 / 96%);
65 | }
66 |
67 | .password-visibility > h3 {
68 | font-size: 16px;
69 | font-weight: 400;
70 | margin: 0 0 30px;
71 | color: var(--color-muted);
72 | }
73 |
74 | .password-visibility > form {
75 | margin: 0;
76 | display: grid;
77 | gap: 16px;
78 | }
79 |
80 | .password-visibility > form > button {
81 | display: flex;
82 | align-items: center;
83 | justify-content: space-between;
84 | cursor: pointer;
85 | padding: 0 12px 0 24px;
86 | border-radius: 6px;
87 | background: var(--color-primary);
88 | color: #f9f9f9;
89 | border: 0;
90 | font-family: inherit;
91 | letter-spacing: 1px;
92 | font-size: 16px;
93 | font-weight: 500;
94 | transition: 0.3s;
95 | }
96 |
97 | .password-visibility form > button:disabled {
98 | opacity: 0.5;
99 | cursor: not-allowed;
100 | }
101 |
102 | .password-visibility p > a {
103 | color: var(--color-primary);
104 | text-decoration: none;
105 | }
106 |
--------------------------------------------------------------------------------
/src/components/controls/PasswordVisibility/PasswordVisibilityExample.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import bg from "./bg.svg";
3 | import "./PasswordVisibilityExample.css";
4 | import { Icon, Password } from "./Password";
5 |
6 | export const PasswordVisibilityExample = () => {
7 | const [state, setState] = useState({
8 | password: "",
9 | });
10 |
11 | const handleInput = (name, value) => {
12 | setState({
13 | ...state,
14 | [name]: value,
15 | });
16 | };
17 |
18 | return (
19 |
20 |
21 |
22 |
Login
23 |
Welcome back Jack!
24 |
31 |
32 |
33 | );
34 | };
35 |
--------------------------------------------------------------------------------
/src/components/controls/index.js:
--------------------------------------------------------------------------------
1 | export * from "./PasswordStrength/PasswordStrength";
2 | export * from "./AutoSuggest/AutoSuggest";
3 | export * from "./PasswordVisibility/PasswordVisibilityExample";
4 | export * from "./EditableText/EditableTextExample";
5 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown1/Dropdown1.css:
--------------------------------------------------------------------------------
1 | .dropdown-1 {
2 | position: relative;
3 | perspective: 1000px;
4 | width: 144px;
5 | }
6 |
7 | .dropdown-1 button {
8 | display: flex;
9 | align-items: center;
10 | gap: 4px;
11 | padding: 0;
12 | width: 100%;
13 | height: 64px;
14 | color: rgb(255 255 255 / 55%);
15 | background: #2d2f31;
16 | border: 0;
17 | cursor: pointer;
18 | font-size: 16px;
19 | font-family: "Euclid Circular A";
20 | }
21 |
22 | .dropdown-1 > button {
23 | background: transparent;
24 | gap: 10px;
25 | margin: 0 -4px;
26 | white-space: nowrap;
27 | }
28 |
29 | .dropdown-1 > button > .chevron {
30 | }
31 |
32 | .dropdown-1:hover > button,
33 | .dropdown-1.open > button {
34 | color: rgb(255 255 255 / 95%);
35 | }
36 |
37 | .dropdown-1.open > button .chevron {
38 | rotate: -180deg;
39 | }
40 |
41 | .dropdown-1 > button > .span {
42 | font-size: 30px;
43 | }
44 |
45 | .dropdown-1 button .chevron {
46 | margin-left: auto;
47 | transition: rotate 0.3s;
48 | }
49 |
50 | .dropdown-1-menu {
51 | position: absolute;
52 | overflow: hidden;
53 | z-index: 1;
54 | top: 64px;
55 | left: 0;
56 | margin: 0 -20px;
57 | width: calc(100% + 40px);
58 | height: 168px;
59 | opacity: 0;
60 | transform: rotateX(-90deg);
61 | transform-origin: 0% 0%;
62 | visibility: hidden;
63 | background: #2d2f31;
64 | transition: 0.3s;
65 | }
66 |
67 | .dropdown-1.open .dropdown-1-menu {
68 | opacity: 1;
69 | transform: rotateX(0);
70 | visibility: visible;
71 | }
72 |
73 | .dropdown-1-menu .main-menu {
74 | width: 50%;
75 | }
76 |
77 | .dropdown-1-menu .menu-inner {
78 | position: absolute;
79 | width: 200%;
80 | display: flex;
81 | transition: 0.4s;
82 | }
83 |
84 | .dropdown-1-menu .menu-inner.open {
85 | translate: -50%;
86 | }
87 |
88 | .dropdown-1-menu button {
89 | border: 0;
90 | height: 56px;
91 | border-radius: 0;
92 | gap: 10px;
93 | padding: 0 8px 0 16px;
94 | text-transform: capitalize;
95 | }
96 |
97 | .dropdown-1-menu button:hover {
98 | color: rgb(255 255 255 / 95%);
99 | }
100 |
101 | .dropdown-1-menu .sub-menu {
102 | position: absolute;
103 | width: 100%;
104 | left: 50%;
105 | top: 0;
106 | }
107 |
108 | .dropdown-1 button .material-symbols-outlined:first-child {
109 | font-size: 22px;
110 | }
111 |
112 | .page.dropdown-1-page {
113 | margin: 0;
114 | display: grid;
115 | place-items: center;
116 | background: #212324;
117 | height: 100vh;
118 | }
119 |
120 | .dropdown-1-nav {
121 | position: fixed;
122 | top: 0;
123 | left: 0;
124 | z-index: 2;
125 | background: #771dff;
126 | width: 100%;
127 | padding: 0 20px;
128 | display: flex;
129 | align-items: center;
130 | justify-content: space-between;
131 | }
132 |
133 | .dropdown-1-nav > h1 {
134 | font-weight: 400;
135 | margin-right: auto;
136 | margin-left: 14px;
137 | font-size: 16px;
138 | }
139 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown1/Dropdown1.jsx:
--------------------------------------------------------------------------------
1 | import { useRef, useState } from "react";
2 | import "./Dropdown1.css";
3 |
4 | const MenuButton = ({
5 | name,
6 | icon,
7 | index,
8 | hasSubItems,
9 | subMenuHeight,
10 | onClick,
11 | }) => {
12 | return (
13 | (onClick ? onClick(index, subMenuHeight) : null)}>
14 | {icon || name}
15 | {name}
16 | {hasSubItems && (
17 | chevron_right
18 | )}
19 |
20 | );
21 | };
22 |
23 | const MenuItem = ({ name, icon, index, activeSubMenu, subItems, onClick }) => {
24 | const subMenuRef = useRef();
25 | const isActive = activeSubMenu === index;
26 | return (
27 | <>
28 | null}
30 | name={name}
31 | icon={icon || name}
32 | index={index}
33 | hasSubItems={Boolean(subItems)}
34 | subMenuHeight={subMenuRef.current?.clientHeight}
35 | />
36 | {subItems?.length && (
37 |
38 | <>
39 |
40 | {subItems.map((subItem) => (
41 |
42 | ))}
43 | >
44 |
45 | )}
46 | >
47 | );
48 | };
49 |
50 | export const Dropdown1 = ({ items }) => {
51 | const [isOpen, setIsOpen] = useState(false);
52 |
53 | const [isSubMenuOpen, setIsSubMenuOpen] = useState(false);
54 |
55 | const [subMenuHeight, setSubMenuHeight] = useState();
56 |
57 | const [activeSubMenu, setActiveSubMenu] = useState();
58 |
59 | const handleClick = (index, subMenuHeight) => {
60 | if (index > -1) setActiveSubMenu(index);
61 | setSubMenuHeight(subMenuHeight);
62 | setIsSubMenuOpen(index > -1);
63 | };
64 |
65 | return (
66 |
67 |
setIsOpen(!isOpen)}>
68 | account_circle
69 | Joe Harrison
70 | expand_more
71 |
72 |
76 |
77 |
78 | {items.map((item, index) => (
79 |
88 | ))}
89 |
90 |
91 |
92 |
93 | );
94 | };
95 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown1/Dropdown1Example.jsx:
--------------------------------------------------------------------------------
1 | import { Dropdown1 } from "./Dropdown1";
2 | import "./Dropdown1.css";
3 |
4 | const items = [
5 | {
6 | name: "settings",
7 | subItems: ["analytics", "database", "terminal"],
8 | },
9 | {
10 | name: "devices",
11 | subItems: ["smartphone", "mouse", "keyboard", "headphones"],
12 | },
13 | {
14 | name: "lock",
15 | displayName: "Account",
16 | },
17 | ];
18 |
19 | export const Dropdown1Example = () => {
20 | return (
21 |
22 |
23 | menu
24 | Dashboard
25 |
26 |
27 |
28 | );
29 | };
30 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown2/Dropdown2.css:
--------------------------------------------------------------------------------
1 | .dropdown-2 {
2 | position: relative;
3 | display: grid;
4 | place-items: center;
5 | height: 72px;
6 | }
7 |
8 | .dropdown-2-overlay {
9 | position: fixed;
10 | inset: 0;
11 | background: rgb(0 0 0 / 40%);
12 | opacity: 0;
13 | visibility: hidden;
14 | transition: 0.3s;
15 | }
16 |
17 | .dropdown-2-overlay.open {
18 | opacity: 1;
19 | visibility: visible;
20 | }
21 |
22 | .dropdown-2 > button {
23 | position: relative;
24 | display: grid;
25 | place-items: center;
26 | width: 36px;
27 | height: 36px;
28 | background: transparent;
29 | }
30 |
31 | .dropdown-2-menu {
32 | overflow-x: hidden;
33 | overflow-y: auto;
34 | position: fixed;
35 | translate: 0 20px;
36 | display: grid;
37 | grid-template-columns: repeat(3, 1fr);
38 | grid-auto-rows: max-content;
39 | width: 270px;
40 | max-height: 286px;
41 | padding: 10px;
42 | background: #ffffff;
43 | border-radius: 8px;
44 | border: 1px solid #ebebeb;
45 | box-shadow: 0 0 10px rgb(0 0 0 / 8%);
46 | opacity: 0;
47 | visibility: hidden;
48 | transition: 0.3s;
49 | appearance: none;
50 | }
51 |
52 | .dropdown-2-menu::-webkit-scrollbar {
53 | width: 15px;
54 | }
55 |
56 | .dropdown-2-menu::-webkit-scrollbar-thumb {
57 | background: #dadce0;
58 | border-radius: 10px;
59 | border: 4px solid transparent;
60 | background-clip: padding-box;
61 | }
62 |
63 | .dropdown-2-menu.open {
64 | opacity: 1;
65 | visibility: visible;
66 | translate: 0;
67 | }
68 |
69 | .dropdown-2-menu > button {
70 | display: flex;
71 | align-items: center;
72 | justify-content: center;
73 | flex-direction: column;
74 | gap: 6px;
75 | font-family: inherit;
76 | color: #6d696b;
77 | border: 0;
78 | background: transparent;
79 | }
80 |
81 | .dropdown-2-menu > button > img {
82 | width: 64px;
83 | height: 64px;
84 | padding: 16px;
85 | }
86 |
87 | .dropdown-2-menu > button > span:first-child {
88 | display: block;
89 | width: 64px;
90 | height: 64px;
91 | scale: 0.7;
92 | background-image: url("./icons.png");
93 | background-position: 0 -3105px;
94 | background-size: 64px 3307px;
95 | background-repeat: no-repeat;
96 | }
97 |
98 | .dropdown-2-menu > button > span:last-child {
99 | font-size: 12px;
100 | translate: 0 -12px;
101 | }
102 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown2/Dropdown2Example.css:
--------------------------------------------------------------------------------
1 | .page.dropdown-2-page {
2 | color: #6d696b;
3 | background: #f7f7f7;
4 | font-family: "Euclid Circular A", "Poppins";
5 | }
6 |
7 | .dropdown-2-nav {
8 | margin-top: -40px;
9 | border-radius: 6px;
10 | display: flex;
11 | align-items: center;
12 | justify-content: space-between;
13 | width: 80%;
14 | height: 72px;
15 | padding: 0 20px;
16 | background: #ffffff;
17 | box-shadow: 0 0 20px rgb(0 0 0 / 6%);
18 | }
19 |
20 | .dropdown-2-nav .logo {
21 | display: flex;
22 | align-items: center;
23 | }
24 |
25 | .dropdown-2-nav .logo img {
26 | width: 36px;
27 | padding: 0;
28 | margin-left: 4px;
29 | margin-right: 6px;
30 | }
31 |
32 | .dropdown-2-nav span.material-symbols-outlined {
33 | display: grid;
34 | place-items: center;
35 | width: 40px;
36 | height: 72px;
37 | font-size: 24px;
38 | }
39 |
40 | .dropdown-2-nav h2 {
41 | font-size: 19px;
42 | font-weight: 400;
43 | }
44 |
45 | .dropdown-2-nav .nav-right > img {
46 | width: 36px;
47 | height: 36px;
48 | border-radius: 50%;
49 | object-fit: contain;
50 | margin-left: 8px;
51 | }
52 |
53 | .dropdown-2-nav button {
54 | background: transparent;
55 | border: 0;
56 | color: inherit;
57 | cursor: pointer;
58 | }
59 |
60 | .dropdown-2-nav .nav-right {
61 | display: flex;
62 | align-items: center;
63 | }
64 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown2/Dropdown2Example.jsx:
--------------------------------------------------------------------------------
1 | import { Dropdown2 } from "./Dropdown2";
2 | import joe from "./joe.png";
3 | import logo from "./logo.svg";
4 | import "./Dropdown2Example.css";
5 |
6 | export const Dropdown2Example = () => {
7 | return (
8 |
9 |
10 |
11 |
menu
12 |
13 |
Joemail
14 |
15 |
16 |
help
17 |
settings
18 |
19 |
20 |
21 |
22 |
23 | );
24 | };
25 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown2/icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/dropdowns/Dropdown2/icons.png
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown2/joe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/dropdowns/Dropdown2/joe.png
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown2/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown3/Dropdown3.css:
--------------------------------------------------------------------------------
1 | .page.dropdown-3-page {
2 | margin: 0;
3 | display: grid;
4 | place-items: center;
5 | background: #1b1921;
6 | height: 100vh;
7 | --color-menu: #2b2935;
8 | }
9 |
10 | .dropdown-3 {
11 | position: relative;
12 | }
13 |
14 | .dropdown-3 button {
15 | display: flex;
16 | align-items: center;
17 | gap: 10px;
18 | padding: 0 16px;
19 | width: 204px;
20 | height: 64px;
21 | color: #afb3b5;
22 | background: var(--color-menu);
23 | border: 0;
24 | cursor: pointer;
25 | font-size: 18px;
26 | font-family: "Euclid Circular A";
27 | transition: 0.3s ease;
28 | }
29 |
30 | .dropdown-3 > button {
31 | background: #6f3dcd;
32 | border-radius: 10px;
33 | color: #f9f9f9;
34 | }
35 |
36 | .dropdown-3.open > button .chevron {
37 | rotate: -180deg;
38 | }
39 |
40 | .dropdown-3 button .chevron {
41 | margin-left: auto;
42 | transition: 0.3s ease;
43 | }
44 |
45 | .dropdown-3 .menu {
46 | position: absolute;
47 | overflow: hidden;
48 | z-index: 1;
49 | top: 74px;
50 | left: 0;
51 | width: 100%;
52 | opacity: 0;
53 | translate: 0 -20px;
54 | visibility: hidden;
55 | border-radius: 10px;
56 | background: var(--color-menu);
57 | transition: 0.4s ease;
58 | }
59 |
60 | .dropdown-3.open .menu {
61 | opacity: 1;
62 | translate: 0;
63 | visibility: visible;
64 | }
65 |
66 | .dropdown-3 .menu-inner {
67 | position: absolute;
68 | width: 460px;
69 | display: flex;
70 | transition: 0.4s ease;
71 | }
72 |
73 | .dropdown-3 .menu-inner.open {
74 | translate: -50%;
75 | }
76 |
77 | .dropdown-3 .menu button {
78 | border: 0;
79 | height: 56px;
80 | border-radius: 0;
81 | text-transform: capitalize;
82 | }
83 |
84 | .dropdown-3 .menu button:hover {
85 | background: #393646;
86 | color: #f9f9f9;
87 | }
88 |
89 | .dropdown-3 .sub-menu {
90 | position: absolute;
91 | width: 230px;
92 | left: 230px;
93 | top: 0;
94 | opacity: 0;
95 | visibility: hidden;
96 | }
97 |
98 | .dropdown-3 .sub-menu.open {
99 | opacity: 1;
100 | visibility: visible;
101 | }
102 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown3/Dropdown3.jsx:
--------------------------------------------------------------------------------
1 | import { useRef, useState } from "react";
2 | import "./Dropdown3.css";
3 |
4 | const items = [
5 | {
6 | name: "build",
7 | subItems: ["description", "folder", "article"],
8 | },
9 | {
10 | name: "devices",
11 | subItems: ["storage", "mouse", "keyboard", "headphones"],
12 | },
13 | {
14 | name: "logout",
15 | },
16 | ];
17 |
18 | const Icon = ({ icon, className }) => (
19 | {icon}
20 | );
21 |
22 | const MenuButton = ({
23 | name,
24 | icon,
25 | index,
26 | hasSubItems,
27 | subMenuHeight,
28 | onClick,
29 | }) => {
30 | return (
31 | (onClick ? onClick(index, subMenuHeight) : null)}>
32 |
33 | {name}
34 | {hasSubItems && }
35 |
36 | );
37 | };
38 |
39 | const MenuItem = ({ name, index, activeSubMenu, subItems, onClick }) => {
40 | const subMenuRef = useRef(null);
41 | const isActive = activeSubMenu === index;
42 | return (
43 | <>
44 | null}
46 | name={name}
47 | index={index}
48 | hasSubItems={Boolean(subItems)}
49 | subMenuHeight={subMenuRef.current?.clientHeight}
50 | />
51 | {subItems?.length && (
52 |
53 | <>
54 |
55 | {subItems.map((subItem) => (
56 |
57 | ))}
58 | >
59 |
60 | )}
61 | >
62 | );
63 | };
64 |
65 | export const Dropdown3 = () => {
66 | const [isOpen, setIsOpen] = useState(false);
67 |
68 | const [isSubMenuOpen, setIsSubMenuOpen] = useState(false);
69 |
70 | const [subMenuHeight, setSubMenuHeight] = useState();
71 |
72 | const [activeSubMenu, setActiveSubMenu] = useState();
73 |
74 | const handleClick = (index, subMenuHeight) => {
75 | if (index > -1) setActiveSubMenu(index);
76 | setSubMenuHeight(subMenuHeight);
77 | setIsSubMenuOpen(index > -1);
78 | };
79 |
80 | return (
81 |
82 |
86 |
setIsOpen(!isOpen)}>
87 |
88 | Kim Wilson
89 |
90 |
91 |
92 |
93 |
94 | {items.map((item, index) => (
95 |
103 | ))}
104 |
105 |
106 |
107 |
108 |
109 | );
110 | };
111 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown4/Dropdown4.css:
--------------------------------------------------------------------------------
1 | .dropdown-4 {
2 | position: relative;
3 | perspective: 400px;
4 | color: #f9f9f9;
5 | font-family: "Euclid Circular A", "Poppins";
6 | }
7 |
8 | .dropdown-4 :is(button, ul, .button-inner) {
9 | transform-origin: 50% 0;
10 | backface-visibility: hidden;
11 | transition: transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275),
12 | background 0.3s, scale 0.3s;
13 | }
14 |
15 | .dropdown-4 button {
16 | position: relative;
17 | z-index: 1;
18 | background: transparent;
19 | border: 0;
20 | color: inherit;
21 | display: flex;
22 | align-items: center;
23 | justify-content: space-between;
24 | font-family: inherit;
25 | height: 60px;
26 | width: 160px;
27 | gap: 12px;
28 | padding: 0 20px 0 32px;
29 | cursor: pointer;
30 | }
31 |
32 | .dropdown-4 > button span {
33 | font-size: 28px;
34 | }
35 |
36 | .dropdown-4 > button .button-inner {
37 | flex: 1 1 auto;
38 | display: flex;
39 | align-items: center;
40 | justify-content: space-between;
41 | font-size: 16px;
42 | }
43 |
44 | .dropdown-4 ul {
45 | position: absolute;
46 | top: 0;
47 | left: 0;
48 | list-style: none;
49 | padding: 0;
50 | margin: 0;
51 | background: #3b1977;
52 | transform: rotateX(-90deg) translateZ(60px);
53 | }
54 |
55 | .dropdown-4.open ul {
56 | transform: rotate(0) translateZ(60px);
57 | }
58 |
59 | .dropdown-4 ul button {
60 | justify-content: flex-start;
61 | gap: 12px;
62 | text-transform: capitalize;
63 | padding: 0 16px;
64 | }
65 |
66 | .dropdown-4 ul button i {
67 | font-size: 20px;
68 | }
69 |
70 | .dropdown-4 ul button:hover {
71 | background: rgb(255 255 255 / 12%);
72 | }
73 |
74 | .dropdown-4 > button {
75 | background: #5d13f1;
76 | transform: rotate(0);
77 | }
78 |
79 | .dropdown-4:not(.open) > button:hover {
80 | scale: 1.05;
81 | }
82 |
83 | .dropdown-4.open > button {
84 | transform: rotateX(90deg);
85 | }
86 |
87 | .dropdown-4.open > button .button-inner {
88 | opacity: 0;
89 | }
90 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown4/Dropdown4.jsx:
--------------------------------------------------------------------------------
1 | import { useRef, useEffect, useState } from "react";
2 | import "./Dropdown4.css";
3 |
4 | // Example items
5 |
6 | // const items = [
7 | // "Trainers",
8 | // "Joggers",
9 | // "Tracksuits"
10 | // ]
11 |
12 | const useClickOutside = (ref, callback) => {
13 | const handleClick = (e) => {
14 | if (ref.current && !ref.current.contains(e.target)) {
15 | callback();
16 | }
17 | };
18 | useEffect(() => {
19 | document.addEventListener("click", handleClick);
20 |
21 | return () => {
22 | document.removeEventListener("click", handleClick);
23 | };
24 | });
25 | };
26 |
27 | export const Dropdown4 = ({ buttonText, items, onItemClick }) => {
28 | const dropdownRef = useRef(null);
29 |
30 | const [isOpen, setIsOpen] = useState(false);
31 |
32 | const toggleIsOpen = () => setIsOpen(!isOpen);
33 |
34 | const handleItemClick = (item) => {
35 | onItemClick(item);
36 | toggleIsOpen();
37 | };
38 |
39 | useClickOutside(dropdownRef, () => setIsOpen(false));
40 |
41 | return (
42 |
43 |
44 |
45 | {buttonText}
46 | arrow_drop_down
47 |
48 |
49 |
50 | {items.map((item) => (
51 |
52 | handleItemClick(item)}>
53 |
54 | {item}
55 |
56 |
57 | ))}
58 |
59 |
60 | );
61 | };
62 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown4/Dropdown4Example.css:
--------------------------------------------------------------------------------
1 | .page.dropdown-4-page {
2 | background: #fdfcf1;
3 | color: #5f5a67;
4 | }
5 |
6 | .page.dropdown-4-page > div {
7 | translate: 0 -60px;
8 | }
9 |
10 | .Toastify__toast {
11 | font-family: inherit;
12 | text-transform: capitalize;
13 | }
14 |
15 | /* .Toastify__toast .Toastify__progress-bar--wrp {
16 | display: none;
17 | } */
18 |
--------------------------------------------------------------------------------
/src/components/dropdowns/Dropdown4/Dropdown4Example.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { ToastContainer, toast, cssTransition } from "react-toastify";
3 | import { Dropdown4 } from "./Dropdown4";
4 | import "./Dropdown4Example.css";
5 |
6 | const items = ["instagram", "twitter", "github"];
7 |
8 | export const Dropdown4Example = () => {
9 | const handleItemClick = (item) =>
10 | toast.success(`Followed on ${item}`, {
11 | position: "bottom-center",
12 | autoClose: true,
13 | closeButton: false,
14 | });
15 |
16 | return (
17 | <>
18 |
19 |
28 | >
29 | );
30 | };
31 |
--------------------------------------------------------------------------------
/src/components/dropdowns/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Dropdown1/Dropdown1Example";
2 | export * from "./Dropdown2/Dropdown2Example";
3 | export * from "./Dropdown3/Dropdown3";
4 | export * from "./Dropdown4/Dropdown4Example";
5 |
--------------------------------------------------------------------------------
/src/components/gsap/ScrollReveal/styles.css:
--------------------------------------------------------------------------------
1 | .scroll-reveal {
2 | display: flex;
3 | flex-wrap: wrap;
4 | justify-content: center;
5 | gap: 20px;
6 | padding: 20px 0;
7 | margin: 0 auto;
8 | }
9 |
10 | .scroll-reveal > div {
11 | background: #121419;
12 | height: 190px;
13 | width: 30%;
14 | opacity: 0;
15 | transition: background 0.3s;
16 | }
17 |
18 | .scroll-reveal > div:hover {
19 | background: #3e70ff;
20 | }
21 |
--------------------------------------------------------------------------------
/src/components/gsap/TypedMessage/TypedMessage.css:
--------------------------------------------------------------------------------
1 | .message {
2 | font-weight: inherit;
3 | line-height: inherit;
4 | font-size: 80px;
5 | text-shadow: 0 0 10px rgb(0 0 0 / 10%);
6 | }
7 |
--------------------------------------------------------------------------------
/src/components/gsap/TypedMessage/TypedMessage.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from "react";
2 | import { gsap } from "gsap";
3 | import { SplitText } from "gsap/all";
4 | import { useGSAP } from "@gsap/react";
5 | import "./TypedMessage.css";
6 |
7 | gsap.registerPlugin(SplitText);
8 |
9 | export const TypedMessage = ({ message }) => {
10 | const blockRef = useRef(null);
11 | const tlRef = useRef();
12 |
13 | useGSAP(() => {
14 | const s = new SplitText(blockRef.current, {
15 | type: "lines,words",
16 | });
17 |
18 | const tl = gsap.timeline({
19 | delay: 0.5,
20 | repeatDelay: 0.5,
21 | repeat: -1,
22 | });
23 |
24 | tl.addLabel("enter");
25 |
26 | tl.fromTo(
27 | s.words,
28 | { yPercent: 100 },
29 | {
30 | yPercent: 0,
31 | ease: "circ.out",
32 | stagger: 0.2,
33 | },
34 | "enter"
35 | );
36 |
37 | tl.fromTo(
38 | s.words,
39 | { opacity: 0 },
40 | {
41 | opacity: 1,
42 | ease: "power1.out",
43 | stagger: 0.2,
44 | },
45 | "enter"
46 | );
47 |
48 | tl.addPause();
49 |
50 | tl.to(
51 | s.words,
52 | {
53 | yPercent: -200,
54 | opacity: 0,
55 | ease: "circ.in",
56 | stagger: 0.1,
57 | duration: 0.4,
58 | },
59 | "exit"
60 | );
61 |
62 | tl.to(
63 | s.words,
64 | {
65 | opacity: 0,
66 | ease: "power1.in",
67 | stagger: 0.1,
68 | duration: 0.4,
69 | },
70 | "exit"
71 | );
72 |
73 | tlRef.current = tl;
74 | }, []);
75 |
76 | const handleClick = () => {
77 | if (tlRef.current) {
78 | tlRef.current.play();
79 | }
80 | };
81 |
82 | return (
83 |
84 | {message}
85 |
86 | );
87 | };
88 |
--------------------------------------------------------------------------------
/src/components/gsap/TypedMessage/TypedMessageExample.css:
--------------------------------------------------------------------------------
1 | .typed-message-page {
2 | color: #222222;
3 | min-height: 100vh;
4 | background: url("./image.jpg");
5 | background-size: cover;
6 | background-position: -360px;
7 | font-family: "Euclid Circular B", "Poppins";
8 | }
9 |
10 | .typed-message-page::before {
11 | content: "";
12 | z-index: 0;
13 | position: absolute;
14 | inset: 0;
15 | background: linear-gradient(rgb(0 0 0 / 86%), rgb(0 0 0 / 0%) 120%);
16 | }
17 |
18 | .typed-message-page nav {
19 | position: fixed;
20 | width: 100%;
21 | z-index: 2;
22 | display: flex;
23 | padding: 0 40px;
24 | align-items: center;
25 | height: 96px;
26 | color: #f7f7f7;
27 | }
28 |
29 | .typed-message-search {
30 | position: relative;
31 | flex: 1 1 auto;
32 | }
33 |
34 | .typed-message-search span {
35 | position: absolute;
36 | z-index: 3;
37 | top: 50%;
38 | left: 16px;
39 | translate: 0 -50%;
40 | }
41 |
42 | .typed-message-search input {
43 | border: 0;
44 | border-radius: 40px;
45 | height: 50px;
46 | background: rgb(255 255 255 / 10%);
47 | backdrop-filter: blur(10px);
48 | width: 100%;
49 | font-family: inherit;
50 | font-size: 16px;
51 | padding-left: 46px;
52 | }
53 |
54 | .typed-message-search input::placeholder {
55 | color: rgb(255 255 255 / 60%);
56 | }
57 |
58 | .typed-message-banner {
59 | position: relative;
60 | height: 100vh;
61 | border-radius: 50px;
62 | color: #ffffff;
63 | }
64 |
65 | .background-video {
66 | position: absolute;
67 | z-index: 0;
68 | inset: 0;
69 | overflow: hidden;
70 | top: 0;
71 | height: 100%;
72 | object-fit: cover;
73 | }
74 |
75 | .banner-overlay {
76 | position: absolute;
77 | z-index: 1;
78 | inset: 0;
79 | background: linear-gradient(rgb(0 0 0 / 40%), rgb(0 0 0 / 0%));
80 | }
81 |
82 | .typed-message-banner-content {
83 | position: relative;
84 | z-index: 3;
85 | padding-top: 320px;
86 | padding-inline: 82px;
87 | display: flex;
88 | flex-direction: column;
89 | gap: 30px;
90 | }
91 |
92 | .typed-message-wrapper {
93 | font-size: 48px;
94 | font-weight: 400;
95 | max-width: 450px;
96 | line-height: 1.2;
97 | }
98 |
99 | .typed-message-banner-content > button {
100 | background: rgb(247 247 247 / 12%);
101 | color: #f7f7f7;
102 | backdrop-filter: blur(10px);
103 | font-family: inherit;
104 | padding: 0 32px;
105 | height: 64px;
106 | border-radius: 32px;
107 | border: 0;
108 | font-size: 22px;
109 | align-self: baseline;
110 | }
111 |
112 | .typed-message-logo {
113 | width: 140px;
114 | padding-right: 40px;
115 | }
116 |
117 | .typed-message-links {
118 | display: flex;
119 | width: 140px;
120 | justify-content: flex-end;
121 | align-items: center;
122 | gap: 16px;
123 | }
124 |
125 | .typed-message-links span {
126 | font-size: 24px;
127 | }
128 |
--------------------------------------------------------------------------------
/src/components/gsap/TypedMessage/TypedMessageExample.jsx:
--------------------------------------------------------------------------------
1 | import { TypedMessage } from "./TypedMessage";
2 | import "./TypedMessageExample.css";
3 | import image from "./image.jpg";
4 | import logo from "./logo.svg";
5 | import video from "./video.mp4";
6 |
7 | export const TypedMessageExample = () => {
8 | return (
9 |
10 |
11 |
12 |
13 | search
14 |
15 |
16 |
17 | mail
18 | notifications
19 | menu
20 |
21 |
22 |
23 |
24 |
25 | Your browser does not support the video tag.
26 |
27 |
32 |
33 |
34 |
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/src/components/gsap/TypedMessage/image.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/gsap/TypedMessage/image.jpg
--------------------------------------------------------------------------------
/src/components/gsap/TypedMessage/video.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/gsap/TypedMessage/video.mp4
--------------------------------------------------------------------------------
/src/components/gsap/index.js:
--------------------------------------------------------------------------------
1 | export * from "./ScrollReveal/ScrollReveal";
2 | export * from "./TypedMessage/TypedMessageExample";
3 |
--------------------------------------------------------------------------------
/src/components/index.js:
--------------------------------------------------------------------------------
1 | export * from "./buttons";
2 | export * from "./carousels";
3 | export * from "./controls";
4 | export * from "./sidebars";
5 | export * from "./gsap";
6 | export * from "./libraries";
7 | export * from "./accordions";
8 | export * from "./logins";
9 | export * from "./cards";
10 | export * from "./modals";
11 | export * from "./parallax";
12 | export * from "./dropdowns";
13 | export * from "./widgets";
14 | export * from "./navbars";
15 | export * from "./tables";
16 | export * from "./signups";
17 |
--------------------------------------------------------------------------------
/src/components/libraries/index.js:
--------------------------------------------------------------------------------
1 | export * from "./rc-slider/RcSlider";
2 | export * from "./react-dropzone/ReactDropzone";
3 | export * from "./react-xarrows/ReactXarrows";
4 |
--------------------------------------------------------------------------------
/src/components/libraries/rc-slider/RcSlider.css:
--------------------------------------------------------------------------------
1 | .page.rc-slider-page {
2 | background: #393965;
3 | font-family: "Euclid Circular A", "Poppins";
4 | }
5 |
6 | .slider-card {
7 | --color-primary: #756bea;
8 | --color-card: #26263c;
9 | display: grid;
10 | gap: 14px;
11 | padding: 20px 20px 24px;
12 | width: 260px;
13 | background: var(--color-card);
14 | border-radius: 10px;
15 | box-shadow: 0 20px 30px rgb(0 0 0 / 10%);
16 | }
17 |
18 | .slider-card h2 {
19 | margin: 0 0 8px;
20 | font-size: 14px;
21 | font-weight: 400;
22 | color: rgb(255 255 255 / 50%);
23 | }
24 |
25 | .slider-card var {
26 | margin: 0;
27 | font-size: 38px;
28 | font-weight: 400;
29 | font-style: normal;
30 | color: rgb(255 255 255 / 100%);
31 | }
32 |
33 | .slider-card var abbr {
34 | color: rgb(255 255 255 / 25%);
35 | margin-right: 4px;
36 | }
37 |
38 | body .rc-slider-rail {
39 | background: rgb(255 255 255 / 12%);
40 | }
41 |
42 | body .rc-slider-handle {
43 | border-color: var(--color-card);
44 | background: var(--color-primary);
45 | opacity: 1;
46 | scale: 1.5;
47 | }
48 |
49 | body .rc-slider-handle:hover,
50 | body .rc-slider-handle-dragging {
51 | box-shadow: none !important;
52 | border-color: var(--color-card) !important;
53 | cursor: pointer;
54 | }
55 |
56 | body .rc-slider-track {
57 | background: var(--color-primary);
58 | }
59 |
--------------------------------------------------------------------------------
/src/components/libraries/rc-slider/RcSlider.jsx:
--------------------------------------------------------------------------------
1 | import Slider from "rc-slider";
2 | import "rc-slider/assets/index.css";
3 | import { useState } from "react";
4 | import "./RcSlider.css";
5 |
6 | export const RcSlider = () => {
7 | const [value, setValue] = useState(20000);
8 |
9 | const handleChange = (val) => setValue(Number(val));
10 |
11 | return (
12 |
13 |
14 |
15 | Mortgage Value
16 |
17 | $
18 | {value.toLocaleString("en-US")}
19 |
20 |
21 |
22 |
23 |
24 | );
25 | };
26 |
--------------------------------------------------------------------------------
/src/components/libraries/react-dropzone/ReactDropzone.css:
--------------------------------------------------------------------------------
1 | .page.dropzone-page {
2 | background: #212224;
3 | --color-card: #161718;
4 | }
5 |
6 | .dropzone-card {
7 | border-radius: 6px;
8 | background: var(--color-card);
9 | padding: 40px;
10 | display: flex;
11 | flex-direction: column;
12 | justify-content: center;
13 | align-items: center;
14 | gap: 16px;
15 | text-align: center;
16 | }
17 |
18 | .dropzone-card h2 {
19 | font-weight: 400;
20 | margin: 0 0 6px;
21 | }
22 |
23 | .dropzone-card h3 {
24 | font-weight: 400;
25 | opacity: 0.5;
26 | margin: 0 0 50px;
27 | }
28 |
29 | .dropzone-card img {
30 | position: absolute;
31 | top: -50px;
32 | width: 100px;
33 | border-radius: 50%;
34 | border: 8px solid var(--color-card);
35 | }
36 |
37 | .dropzone {
38 | position: relative;
39 | flex: 1;
40 | display: flex;
41 | flex-direction: column;
42 | align-items: center;
43 | justify-content: center;
44 | padding: 20px;
45 | width: 280px;
46 | min-height: 200px;
47 | border-width: 2px;
48 | border-radius: 6px;
49 | border-color: #464646;
50 | border-style: dashed;
51 | background-color: transparent;
52 | color: #bdbdbd;
53 | outline: none;
54 | }
55 |
--------------------------------------------------------------------------------
/src/components/libraries/react-dropzone/ReactDropzone.jsx:
--------------------------------------------------------------------------------
1 | import "./ReactDropzone.css";
2 | import { useDropzone } from "react-dropzone";
3 | import icon from "./icon.svg";
4 |
5 | export const ReactDropzone = () => {
6 | const onDrop = (acceptedFiles) => {
7 | // Do something with the files
8 | };
9 | const { getRootProps, getInputProps, isDragActive, acceptedFiles } =
10 | useDropzone({ onDrop });
11 | const files = acceptedFiles.map((file) => (
12 | {file.path}
13 | ));
14 |
15 | return (
16 |
17 |
18 |
19 |
Upload Files
20 | Fast and easy
21 |
22 |
23 |
24 |
25 | {isDragActive ? (
26 |
Drop the files here ...
27 | ) : (
28 |
Drag 'n' drop some files here, or click to select files
29 | )}
30 |
31 | {files.length > 0 && (
32 | <>
33 |
Files
34 |
35 | >
36 | )}
37 |
38 |
39 | );
40 | };
41 |
--------------------------------------------------------------------------------
/src/components/libraries/react-dropzone/icon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
7 |
12 |
13 |
18 |
24 |
25 |
--------------------------------------------------------------------------------
/src/components/libraries/react-xarrows/ReactXarrows.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/libraries/react-xarrows/ReactXarrows.css
--------------------------------------------------------------------------------
/src/components/libraries/react-xarrows/ReactXarrows.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Xarrow, { useXarrow, Xwrapper } from "react-xarrows";
3 | import Draggable from "react-draggable";
4 |
5 | const boxStyle = {
6 | border: "grey solid 2px",
7 | borderRadius: "10px",
8 | padding: "5px",
9 | };
10 |
11 | const DraggableBox = ({ id }) => {
12 | const updateXarrow = useXarrow();
13 | return (
14 |
15 |
16 | {id}
17 |
18 |
19 | );
20 | };
21 |
22 | export const ReactXarrows = () => {
23 | return (
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | );
34 | };
35 |
--------------------------------------------------------------------------------
/src/components/logins/Login1/Login1.jsx:
--------------------------------------------------------------------------------
1 | import "./styles.css";
2 | import logo from "./logo.svg";
3 |
4 | export const Login1 = () => {
5 | return (
6 |
7 |
8 |
9 |
10 |
Welcome back
11 |
16 |
17 | Need an account? Sign up here
18 |
19 |
20 |
21 | );
22 | };
23 |
--------------------------------------------------------------------------------
/src/components/logins/Login1/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/components/logins/Login1/styles.css:
--------------------------------------------------------------------------------
1 | .page.login-1 {
2 | display: grid;
3 | place-items: center;
4 | gap: 50px;
5 | margin: 0;
6 | height: 100vh;
7 | padding: 0 32px;
8 | color: #aaaaaa;
9 | background: #eff9ff;
10 | font-family: "Euclid Circular A", "Poppins";
11 | }
12 |
13 | @media (width >= 500px) {
14 | .page.login-1 {
15 | padding: 0;
16 | }
17 | }
18 |
19 | .login-1-background {
20 | position: fixed;
21 | top: -50vmin;
22 | left: -50vmin;
23 | width: 100vmin;
24 | height: 100vmin;
25 | border-radius: 47% 53% 61% 39% / 45% 51% 49% 55%;
26 | background: #65c8ff;
27 | }
28 |
29 | .login-1-background::after {
30 | content: "";
31 | position: inherit;
32 | right: -50vmin;
33 | bottom: -55vmin;
34 | width: inherit;
35 | height: inherit;
36 | border-radius: inherit;
37 | background: #143d81;
38 | }
39 |
40 | .login-1-card {
41 | overflow: hidden;
42 | position: relative;
43 | z-index: 3;
44 | width: 94%;
45 | margin: 0 20px;
46 | padding: 170px 30px 54px;
47 | border-radius: 24px;
48 | background: #ffffff;
49 | text-align: center;
50 | box-shadow: 0 100px 100px rgb(0 0 0 / 10%);
51 | }
52 |
53 | .login-1-card::before {
54 | content: "";
55 | position: absolute;
56 | top: -880px;
57 | left: 50%;
58 | translate: -50% 0;
59 | width: 1000px;
60 | height: 1000px;
61 | border-radius: 50%;
62 | background: #216ce7;
63 | }
64 |
65 | @media (width >= 500px) {
66 | .login-1-card {
67 | margin: 0;
68 | width: 360px;
69 | }
70 | }
71 |
72 | .login-1-card > img {
73 | position: absolute;
74 | top: 30px;
75 | left: 50%;
76 | translate: -50% 0;
77 | width: 64px;
78 | height: 64px;
79 | }
80 |
81 | .login-1-card > h2 {
82 | font-size: 22px;
83 | font-weight: 400;
84 | margin: 0 0 38px;
85 | color: rgb(0 0 0 / 38%);
86 | }
87 |
88 | .login-1-card form {
89 | margin: 0 0 44px;
90 | display: grid;
91 | gap: 12px;
92 | }
93 |
94 | .login-1-card form :is(input, button) {
95 | width: 100%;
96 | height: 56px;
97 | border-radius: 28px;
98 | font-size: 16px;
99 | font-family: inherit;
100 | }
101 |
102 | .login-1-card form > input {
103 | border: 0;
104 | padding: 0 24px;
105 | color: #222222;
106 | background: #ededed;
107 | }
108 |
109 | .login-1-card form > input::placeholder {
110 | color: rgb(0 0 0 / 28%);
111 | }
112 |
113 | .login-1-card form > button {
114 | border: 0;
115 | color: #f9f9f9;
116 | background: #226ce7;
117 | display: grid;
118 | place-items: center;
119 | font-weight: 500;
120 | cursor: pointer;
121 | }
122 |
123 | .login-1-card form > footer {
124 | color: #a1a1a1;
125 | }
126 |
127 | .login-1-card form > footer > a {
128 | color: #216ce7;
129 | }
130 |
--------------------------------------------------------------------------------
/src/components/logins/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Login1/Login1";
2 |
--------------------------------------------------------------------------------
/src/components/modals/Modal1/Modal1.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./styles.css";
3 | import logo from "./logo.svg";
4 |
5 | export const Modal1 = () => {
6 | const [isOpen, setIsOpen] = useState(false);
7 |
8 | const toggleModal = () => setIsOpen(!isOpen);
9 |
10 | return (
11 |
12 |
16 |
17 |
18 | Sign Up
19 | Try Hologram today
20 |
21 |
39 |
No credit card information required
40 |
41 |
42 |
43 |
44 |
45 | Try Hologram today.
46 |
51 | Sign up free
52 | trending_flat
53 |
54 |
55 |
56 |
57 |
87 |
88 |
89 |
90 |
91 | );
92 | };
93 |
--------------------------------------------------------------------------------
/src/components/modals/Modal2/Modal2 copy.css:
--------------------------------------------------------------------------------
1 | .overlay,
2 | .dialog {
3 | position: fixed;
4 | }
5 |
6 | @keyframes overlay-in {
7 | 0% {
8 | scale: 0 0.003;
9 | }
10 | 33%,
11 | 36% {
12 | scale: 1 0.003;
13 | }
14 | 66%,
15 | 100% {
16 | scale: 1 1;
17 | }
18 | }
19 |
20 | .overlay {
21 | z-index: 1;
22 | top: 0;
23 | left: 0;
24 | right: 0;
25 | bottom: 0;
26 | background: rgb(0 0 0 / 75%);
27 | display: grid;
28 | place-items: center;
29 | }
30 |
31 | .overlay.open {
32 | animation: overlay-in 1s both;
33 | }
34 |
35 | .overlay.closed {
36 | animation: overlay-in 1s 0.25s reverse both;
37 | }
38 |
39 | .overlay.default {
40 | scale: 0;
41 | }
42 |
43 | @keyframes modal-in {
44 | 0% {
45 | opacity: 0;
46 | visibility: hidden;
47 | scale: 0.5;
48 | }
49 | 100% {
50 | opacity: 1;
51 | visibility: visible;
52 | scale: 1;
53 | }
54 | }
55 |
56 | .dialog {
57 | z-index: 2;
58 | width: 380px;
59 | top: 50%;
60 | left: 50%;
61 | background: #ffffff;
62 | border-radius: 12px;
63 | padding: 0 40px 50px;
64 | translate: -50% -50%;
65 | box-shadow: 0 10px 30px rgb(0 0 0 / 24%);
66 | }
67 |
68 | .dialog.default {
69 | opacity: 0;
70 | visibility: hidden;
71 | }
72 |
73 | .dialog.open {
74 | animation: modal-in 0.5s 0.6s both;
75 | }
76 |
77 | .dialog.closed {
78 | animation: modal-in 0.5s reverse both;
79 | }
80 |
81 | .dialog header {
82 | background: linear-gradient(90deg, #9d50bb, #6e48aa);
83 | margin: -85px -20px 30px;
84 | border-radius: 12px;
85 | height: 170px;
86 | display: flex;
87 | justify-content: center;
88 | flex-direction: column;
89 | padding-left: 40px;
90 | box-shadow: 0 16px 30px rgb(0 0 0 / 12%);
91 | }
92 |
93 | .dialog header h2 {
94 | margin-bottom: 10px;
95 | font-size: 29px;
96 | }
97 |
98 | .dialog header h3 {
99 | opacity: 0.45;
100 | font-weight: 400;
101 | }
102 |
--------------------------------------------------------------------------------
/src/components/modals/Modal2/Modal2.css:
--------------------------------------------------------------------------------
1 | .modal-2-overlay,
2 | .modal-2-modal {
3 | position: fixed;
4 | }
5 |
6 | @keyframes overlay-in {
7 | 0% {
8 | scale: 0 0.003;
9 | }
10 | 33%,
11 | 36% {
12 | scale: 1 0.003;
13 | }
14 | 66%,
15 | 100% {
16 | scale: 1 1;
17 | }
18 | }
19 |
20 | .modal-2-overlay {
21 | z-index: 1;
22 | top: 0;
23 | left: 0;
24 | right: 0;
25 | bottom: 0;
26 | background: rgb(0 0 0 / 75%);
27 | display: grid;
28 | place-items: center;
29 | }
30 |
31 | .modal-2-overlay.open {
32 | animation: overlay-in 1s both;
33 | }
34 |
35 | .modal-2-overlay.closed {
36 | animation: overlay-in 1s 0.25s reverse both;
37 | }
38 |
39 | .modal-2-overlay.default {
40 | scale: 0;
41 | }
42 |
43 | @keyframes modal-in {
44 | 0% {
45 | opacity: 0;
46 | visibility: hidden;
47 | scale: 0.5;
48 | }
49 | 100% {
50 | opacity: 1;
51 | visibility: visible;
52 | scale: 1;
53 | }
54 | }
55 |
56 | .modal-2-modal {
57 | z-index: 2;
58 | width: 380px;
59 | top: 50%;
60 | left: 50%;
61 | background: #ffffff;
62 | border-radius: 12px;
63 | padding: 0 40px 50px;
64 | translate: -50% -50%;
65 | box-shadow: 0 10px 30px rgb(0 0 0 / 24%);
66 | }
67 |
68 | .modal-2-modal.default {
69 | opacity: 0;
70 | visibility: hidden;
71 | }
72 |
73 | .modal-2-modal.open {
74 | animation: modal-in 0.5s 0.6s both;
75 | }
76 |
77 | .modal-2-modal.closed {
78 | animation: modal-in 0.5s reverse both;
79 | }
80 |
81 | .modal-2-modal header {
82 | background: linear-gradient(90deg, #9d50bb, #6e48aa);
83 | margin: -85px -20px 30px;
84 | border-radius: 12px;
85 | height: 170px;
86 | display: flex;
87 | justify-content: center;
88 | flex-direction: column;
89 | padding-left: 40px;
90 | box-shadow: 0 16px 30px rgb(0 0 0 / 12%);
91 | }
92 |
93 | .modal-2-modal header h2 {
94 | margin-bottom: 10px;
95 | font-size: 29px;
96 | }
97 |
98 | .modal-2-modal header h3 {
99 | opacity: 0.45;
100 | font-weight: 400;
101 | }
102 |
--------------------------------------------------------------------------------
/src/components/modals/Modal2/Modal2.jsx:
--------------------------------------------------------------------------------
1 | import { createPortal } from "react-dom";
2 | import "./Modal2.css";
3 |
4 | export const Modal2 = ({
5 | title,
6 | subtitle,
7 | modalContent,
8 | toggleModal,
9 | isOpen,
10 | }) => {
11 | const open = isOpen === null ? "default" : isOpen ? "open" : "closed";
12 |
13 | const Overlay = () => (
14 |
15 | );
16 |
17 | const Dialog = () => (
18 | e.stopPropagation()}
21 | >
22 |
23 | {title}
24 | {subtitle}
25 |
26 | {modalContent}
27 |
28 | );
29 |
30 | return (
31 | <>
32 | {createPortal( , document.body)}
33 | {createPortal( , document.body)}
34 | >
35 | );
36 | };
37 |
--------------------------------------------------------------------------------
/src/components/modals/Modal2/Modal2Example.css:
--------------------------------------------------------------------------------
1 | .page.modal-2-page {
2 | background: #ffffff;
3 | }
4 |
5 | .page.modal-2-page .container {
6 | max-width: 700px;
7 | margin: 0 auto;
8 | }
9 |
10 | .modal-2-footer {
11 | position: fixed;
12 | left: 0;
13 | bottom: 0;
14 | right: 0;
15 | height: calc(50vh + 1px);
16 | padding-bottom: 20px;
17 | background: #161022;
18 | color: #e5e2e9;
19 | }
20 |
21 | .modal-2-footer article {
22 | display: flex;
23 | flex-direction: column;
24 | align-items: center;
25 | justify-content: space-between;
26 | gap: 16px;
27 | padding: 20px 40px 40px;
28 | margin: -99px 20px 20px;
29 | border-radius: 10px;
30 | background: linear-gradient(90deg, #9d50bb, #6e48aa);
31 | }
32 |
33 | .modal-2-footer article h2 {
34 | font-weight: 400;
35 | color: #f9f9f9;
36 | }
37 |
38 | .signup-button {
39 | display: flex;
40 | align-items: center;
41 | justify-content: space-between;
42 | gap: 10px;
43 | padding: 0 20px 0 20px;
44 | width: 100%;
45 | height: 56px;
46 | background: #161022;
47 | border: 0;
48 | border-radius: 6px;
49 | color: #e5e2e9;
50 | font-family: inherit;
51 | font-size: 16px;
52 | cursor: pointer;
53 | }
54 |
55 | .modal-2-footer section {
56 | padding: 0 50px;
57 | }
58 |
59 | .modal-2-footer section.top {
60 | padding-top: 30px;
61 | margin-bottom: 48px;
62 | }
63 |
64 | .modal-2-footer section.top img {
65 | display: block;
66 | height: 30px;
67 | margin: 0 0 30px;
68 | }
69 |
70 | .modal-2-footer section.top ul {
71 | list-style: none;
72 | padding: 0;
73 | margin: 0;
74 | display: grid;
75 | gap: 30px;
76 | grid-template-columns: repeat(2, 1fr);
77 | }
78 |
79 | @media (width > 480px) {
80 | .modal-2-footer article button {
81 | width: 70%;
82 | }
83 |
84 | .modal-2-footer section.top ul {
85 | padding-right: 10%;
86 | }
87 | }
88 |
89 | @media (width > 600px) {
90 | .modal-2-footer article {
91 | flex-direction: row;
92 | min-height: 140px;
93 | margin: -70px 20px 20px;
94 | padding: 30px 50px 30px;
95 | }
96 |
97 | .modal-2-footer article button {
98 | width: auto;
99 | padding: 0 20px 0 24px;
100 | }
101 |
102 | .modal-2-footer section.top ul {
103 | grid-template-columns: repeat(4, 1fr);
104 | padding-right: 0;
105 | }
106 | }
107 |
108 | .modal-2-footer section.top ul li a {
109 | display: block;
110 | margin-bottom: 18px;
111 | color: #e5e2e9;
112 | }
113 |
114 | .modal-2-footer section.top h3 {
115 | color: #9a90a9;
116 | font-weight: 400;
117 | text-transform: uppercase;
118 | font-size: 12px;
119 | letter-spacing: 1px;
120 | margin-bottom: 20px;
121 | }
122 |
123 | .modal-2-modal form {
124 | display: grid;
125 | gap: 16px;
126 | }
127 |
128 | .modal-2-modal input {
129 | border: 0;
130 | background: #ececec;
131 | height: 56px;
132 | border-radius: 6px;
133 | font-family: inherit;
134 | padding: 0 20px;
135 | font-size: 16px;
136 | }
137 |
138 | .modal-2-modal input::placeholder {
139 | color: #96939c;
140 | }
141 |
142 | .modal-2-modal > p {
143 | color: #96939c;
144 | margin: 30px 0 0;
145 | text-align: center;
146 | }
147 |
--------------------------------------------------------------------------------
/src/components/modals/Modal2/Modal2Example.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./Modal2Example.css";
3 | import { Modal2 } from "./Modal2";
4 | import logo from "./logo.svg";
5 |
6 | export const Modal2Example = () => {
7 | const [isOpen, setIsOpen] = useState(null);
8 |
9 | const toggleModal = () => setIsOpen(!isOpen);
10 |
11 | return (
12 |
13 |
20 |
31 | No credit card information required
32 | >
33 | }
34 | />
35 |
36 |
37 |
38 | Try Hologram today.
39 |
44 | Sign up free
45 | trending_flat
46 |
47 |
48 |
49 |
50 |
80 |
81 |
82 |
83 |
84 | );
85 | };
86 |
--------------------------------------------------------------------------------
/src/components/modals/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Modal1/Modal1";
2 | export * from "./Modal2/Modal2";
3 | export * from "./Modal2/Modal2Example";
4 |
--------------------------------------------------------------------------------
/src/components/navbars/Navbar1/Navbar1.css:
--------------------------------------------------------------------------------
1 | .page.navbar-1-page {
2 | background: #09090b;
3 | color: #faf9f5;
4 | font-family: "Euclid Circular A", "Poppins";
5 | padding-top: 72px;
6 | margin: 0;
7 | }
8 |
9 | .navbar-1 {
10 | position: fixed;
11 | z-index: 1;
12 | top: 0;
13 | left: 0;
14 | translate: 0 -72px;
15 | display: flex;
16 | align-items: center;
17 | justify-content: space-between;
18 | gap: 20px;
19 | padding: 0 20px;
20 | width: 100%;
21 | height: 72px;
22 | box-shadow: 0 10px 20px rgb(0 0 0 / 10%);
23 | background: #4f52ff;
24 | transition: 0.3s;
25 | }
26 |
27 | .navbar-1.visible {
28 | top: 0;
29 | translate: 0;
30 | }
31 |
32 | .navbar-1 > h1 {
33 | width: 36px;
34 | height: 36px;
35 | background: #f9f9f9;
36 | color: #4f52ff;
37 | display: grid;
38 | place-items: center;
39 | border-radius: 50%;
40 | }
41 |
42 | .navbar-1 .nav-items {
43 | display: flex;
44 | align-items: center;
45 | gap: 16px;
46 | }
47 |
48 | .navbar-1 .nav-items > a {
49 | text-decoration: none;
50 | font-weight: 400;
51 | color: rgb(255 255 255 / 96%);
52 | height: 72px;
53 | display: grid;
54 | place-items: center;
55 | }
56 |
57 | .navbar-1 .nav-items > a:hover {
58 | color: rgb(255 255 255 / 96%);
59 | }
60 |
61 | .page.navbar-1-page h2 {
62 | font-size: 20px;
63 | margin: 0 0 4px;
64 | cursor: default;
65 | }
66 |
67 | .page.navbar-1-page section {
68 | display: flex;
69 | align-items: center;
70 | gap: 40px;
71 | padding: 100px 60px;
72 | }
73 |
74 | .page.navbar-1-page p {
75 | opacity: 0.6;
76 | }
77 |
78 | .page.navbar-1-page section.shaded {
79 | background: #0e0e11;
80 | }
81 |
82 | .page.navbar-1-page section > img {
83 | width: 200px;
84 | height: 200px;
85 | }
86 |
87 | .page.navbar-1-page section.shaded > img {
88 | padding: 20px;
89 | }
90 |
91 | .page.navbar-1-page section > p {
92 | line-height: 1.7;
93 | }
94 |
--------------------------------------------------------------------------------
/src/components/navbars/Navbar2/Navbar2.css:
--------------------------------------------------------------------------------
1 | .navbar-2 {
2 | position: fixed;
3 | top: 0;
4 | left: 0;
5 | right: 0;
6 | height: 72px;
7 | border-bottom: 1px solid rgb(255 255 255 / 10%);
8 | display: flex;
9 | align-items: center;
10 | padding: 0 24px;
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/navbars/Navbar2/Navbar2.jsx:
--------------------------------------------------------------------------------
1 | export const Navbar2 = () => {
2 | return (
3 |
4 |
5 | change_history
6 |
7 |
8 | );
9 | };
10 |
--------------------------------------------------------------------------------
/src/components/navbars/Navbar3/Navbar3.css:
--------------------------------------------------------------------------------
1 | .page.navbar-3-page {
2 | background: #f8f7ff;
3 | font-family: "Euclid Circular A", "Poppins";
4 | }
5 |
6 | .navbar-3 {
7 | --color-primary: #6f5bf3;
8 | position: fixed;
9 | top: 0;
10 | left: 0;
11 | z-index: 1;
12 | display: flex;
13 | align-items: center;
14 | padding: 0 20px;
15 | height: 72px;
16 | width: 100%;
17 | background: #ffffff;
18 | color: #5b5968;
19 | box-shadow: 0 10px 50px rgb(0 0 0 / 2%);
20 | }
21 |
22 | .navbar-3 a {
23 | padding: 0 12px;
24 | display: flex;
25 | align-items: center;
26 | cursor: pointer;
27 | width: 100%;
28 | height: 72px;
29 | font-size: 15px;
30 | }
31 |
32 | .navbar-3 > img {
33 | margin: 0 24px 0 0;
34 | height: 36px;
35 | width: 36px;
36 | }
37 |
38 | .navbar-3-menu {
39 | display: flex;
40 | align-items: center;
41 | justify-content: center;
42 | font-weight: 500;
43 | }
44 |
45 | .navbar-3-dropdown {
46 | position: fixed;
47 | z-index: 1;
48 | top: 82px;
49 | left: 0;
50 | height: 0;
51 | width: 120px;
52 | padding: 6px 0;
53 | overflow: hidden;
54 | display: grid;
55 | opacity: 0;
56 | visibility: hidden;
57 | transition: 0.3s;
58 | border-radius: 6px;
59 | background: #ffffff;
60 | box-shadow: 0 0 30px rgb(0 0 0 / 4%);
61 | transition: 0.3s;
62 | }
63 |
64 | .navbar-3 a:is(:hover, .active) {
65 | color: var(--color-primary);
66 | }
67 |
68 | .navbar-3-dropdown.visible {
69 | opacity: 1;
70 | visibility: visible;
71 | height: max-content;
72 | }
73 |
74 | .navbar-3-dropdown::after {
75 | content: "";
76 | position: absolute;
77 | inset: 0;
78 | top: -12px;
79 | }
80 |
81 | .navbar-3-dropdown > a {
82 | position: relative;
83 | z-index: 1;
84 | height: 40px;
85 | font-size: 14px;
86 | white-space: nowrap;
87 | }
88 |
89 | .navbar-3-search {
90 | position: relative;
91 | margin-left: auto;
92 | }
93 |
94 | .navbar-3-search span {
95 | position: absolute;
96 | top: 50%;
97 | left: 12px;
98 | translate: 0 -50%;
99 | font-size: 18px;
100 | }
101 |
102 | .navbar-3-search input {
103 | border: 0;
104 | border-radius: 6px;
105 | height: 36px;
106 | width: 100%;
107 | max-width: 200px;
108 | background: #f6f5fd;
109 | padding-left: 36px;
110 | font-size: 15px;
111 | }
112 |
113 | .navbar-3-search span,
114 | .navbar-3-search input::placeholder {
115 | color: #9b98b1;
116 | }
117 |
--------------------------------------------------------------------------------
/src/components/navbars/Navbar3/Navbar3.jsx:
--------------------------------------------------------------------------------
1 | import { useRef, useState } from "react";
2 | import avatar from "./avatar.png";
3 | import "./Navbar3.css";
4 |
5 | const items = [
6 | {
7 | name: "About",
8 | },
9 | {
10 | name: "Skills",
11 | items: ["UI/UX", "Development", "Design"],
12 | },
13 | {
14 | name: "Projects",
15 | items: ["Chatbot", "Calculator", "Weather"],
16 | },
17 | {
18 | name: "Work",
19 | items: ["Portfolio", "Resume", "GitHub"],
20 | },
21 | ];
22 |
23 | const Link = ({ item, activeItem, onHover }) => {
24 | const linkRef = useRef();
25 |
26 | const handleHover = () => {
27 | const rect = linkRef.current.getBoundingClientRect();
28 | onHover(item, `${rect.x}px`);
29 | };
30 |
31 | return (
32 |
37 | {item.name}
38 |
39 | );
40 | };
41 |
42 | const Search = () => (
43 |
44 | search
45 |
46 |
47 | );
48 |
49 | export const Navbar3 = () => {
50 | const [translateX, setTranslateX] = useState("0");
51 | const [activeItem, setActiveItem] = useState(null);
52 |
53 | const handleLinkHover = (item, x) => {
54 | setActiveItem(item || null);
55 | setTranslateX(x);
56 | };
57 |
58 | return (
59 |
60 |
61 |
62 |
63 | {items.map((item) => (
64 |
69 | ))}
70 |
76 | {activeItem?.items?.map((link) => (
77 |
{link}
78 | ))}
79 |
80 |
81 |
82 |
83 |
84 | );
85 | };
86 |
--------------------------------------------------------------------------------
/src/components/navbars/Navbar3/avatar.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/navbars/Navbar3/avatar.png
--------------------------------------------------------------------------------
/src/components/navbars/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Navbar1/Navbar1";
2 | export * from "./Navbar2/Navbar2";
3 | export * from "./Navbar3/Navbar3";
4 |
--------------------------------------------------------------------------------
/src/components/parallax/index.js:
--------------------------------------------------------------------------------
1 | export * from "./parallax-1/Parallax1";
2 |
--------------------------------------------------------------------------------
/src/components/parallax/parallax-1/Parallax1.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import "./styles.css";
3 |
4 | export const Parallax1 = () => {
5 | const [scrollPosition, setScrollPosition] = useState(0);
6 |
7 | const handleScroll = () => setScrollPosition(window.scrollY);
8 |
9 | useEffect(() => {
10 | window.addEventListener("scroll", handleScroll, { passive: true });
11 |
12 | return () => {
13 | window.removeEventListener("scroll", handleScroll);
14 | };
15 | }, []);
16 |
17 | return (
18 |
19 |
25 | Parallax
26 | Get Started
27 |
28 |
29 | What is parallax?
30 |
31 | Parallax is a displacement or difference in the apparent position of
32 | an object viewed along two different lines of sight and is measured by
33 | the angle or half-angle of inclination between those two lines. Due to
34 | foreshortening, nearby objects show a larger parallax than farther
35 | objects, so parallax can be used to determine distances.
36 |
37 |
38 | Parallax also affects optical instruments such as rifle scopes,
39 | binoculars, microscopes, and twin-lens reflex cameras that view
40 | objects from slightly different angles. Many animals, along with
41 | humans, have two eyes with overlapping visual fields that use parallax
42 | to gain depth perception; this process is known as stereopsis. In
43 | computer vision the effect is used for computer stereo vision, and
44 | there is a device called a parallax rangefinder that uses it to find
45 | the range, and in some variations also altitude to a target.
46 |
47 |
48 | Parallax is a displacement or difference in the apparent position of
49 | an object viewed along two different lines of sight and is measured by
50 | the angle or half-angle of inclination between those two lines. Due to
51 | foreshortening, nearby objects show a larger parallax than farther
52 | objects, so parallax can be used to determine distances.
53 |
54 |
55 | Parallax also affects optical instruments such as rifle scopes,
56 | binoculars, microscopes, and twin-lens reflex cameras that view
57 | objects from slightly different angles. Many animals, along with
58 | humans, have two eyes with overlapping visual fields that use parallax
59 | to gain depth perception; this process is known as stereopsis. In
60 | computer vision the effect is used for computer stereo vision, and
61 | there is a device called a parallax rangefinder that uses it to find
62 | the range, and in some variations also altitude to a target.
63 |
64 |
65 |
66 | );
67 | };
68 |
--------------------------------------------------------------------------------
/src/components/parallax/parallax-1/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/parallax/parallax-1/bg.png
--------------------------------------------------------------------------------
/src/components/parallax/parallax-1/styles.css:
--------------------------------------------------------------------------------
1 | .page.parallax-1-page {
2 | background: #0e0d0e;
3 | height: 100%;
4 | font-family: "Euclid Circular A", "Poppins";
5 | }
6 |
7 | * {
8 | box-sizing: border-box;
9 | }
10 |
11 | .parallax-banner {
12 | display: flex;
13 | justify-content: center;
14 | align-items: center;
15 | flex-direction: column;
16 | background-image: url("./bg.png");
17 | background-size: cover;
18 | background-repeat: no-repeat;
19 | background-position: 50% 70%;
20 | height: 600px;
21 | width: 100vw;
22 | transition: 0.05s linear;
23 | }
24 |
25 | .parallax-banner h2 {
26 | font-size: 48px;
27 | color: #f8f8f8;
28 | padding-top: 0;
29 | margin-top: 0;
30 | margin-bottom: 10px;
31 | }
32 |
33 | .parallax-banner button {
34 | border: 0;
35 | background: #ffffff;
36 | color: #222222;
37 | padding: 10px 24px;
38 | border-radius: 30px;
39 | font-family: inherit;
40 | font-size: 16px;
41 | font-weight: 600;
42 | }
43 |
44 | .parallax-container {
45 | padding: 0 10%;
46 | }
47 |
48 | .parallax-banner h2 {
49 | margin-top: 0;
50 | margin-bottom: 40px;
51 | padding-top: 60px;
52 | }
53 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar1/styles.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | .page.sidebar-1-page {
6 | margin: 0;
7 | background: #12131a;
8 | font-family: "Euclid Circular A";
9 | }
10 |
11 | .sidebar-1 button {
12 | background: transparent;
13 | border: 0;
14 | padding: 0;
15 | cursor: pointer;
16 | text-align: left;
17 | }
18 |
19 | .sidebar-1 {
20 | position: fixed;
21 | top: 0;
22 | left: 0;
23 | display: flex;
24 | flex-direction: column;
25 | gap: 8px;
26 | width: 260px;
27 | height: 100%;
28 | padding: 0 16px;
29 | background: #1d212a;
30 | border-right: 1px solid #2e303e;
31 | transition: width 0.4s;
32 | }
33 |
34 | .sidebar-1 .sidebar-header {
35 | display: flex;
36 | align-items: center;
37 | height: 72px;
38 | padding: 0 1.25rem 0 0;
39 | border-bottom: 1px solid #2e303e;
40 | color: #e1ecff;
41 | }
42 |
43 | .sidebar-1 .sidebar-header button {
44 | width: 54px;
45 | }
46 |
47 | .sidebar-1 .sidebar-logo {
48 | height: 20px;
49 | }
50 |
51 | .sidebar-1 button {
52 | position: relative;
53 | display: flex;
54 | gap: 16px;
55 | align-items: center;
56 | height: 50px;
57 | width: 100%;
58 | border-radius: 6px;
59 | font-family: inherit;
60 | font-size: 16px;
61 | font-weight: 400;
62 | line-height: 1;
63 | padding: 0 16px;
64 | color: #e1ecff;
65 | transition: background 0.3s;
66 | }
67 |
68 | .sidebar-1 button span:nth-child(2) {
69 | flex: 1 1 auto;
70 | }
71 |
72 | .sidebar-1 button:is(.active, :hover) {
73 | background: #004fee;
74 | color: #e1ecff;
75 | }
76 |
77 | .sidebar-1 button span {
78 | transition: 0.3s;
79 | }
80 |
81 | .sidebar-1 button.active > span:nth-child(3) {
82 | rotate: -180deg;
83 | }
84 |
85 | .sidebar-1 button:not(.active):hover {
86 | background: #2e303e;
87 | }
88 |
89 | .sidebar-1 .sub-nav button.active::before {
90 | background: #e1ecff;
91 | }
92 |
93 | .sidebar-1 .sub-nav {
94 | overflow: hidden;
95 | /* height: 0; */
96 | transition: 0.5s;
97 | }
98 |
99 | /* .sub-nav.open {
100 | height: 200px;
101 | } */
102 |
103 | .sidebar-1 .sub-nav button {
104 | padding-left: 54px;
105 | }
106 |
107 | .sidebar-1 .sub-nav button::before {
108 | content: "";
109 | position: absolute;
110 | top: 50%;
111 | left: 25px;
112 | translate: 0 -50%;
113 | width: 5px;
114 | height: 5px;
115 | border-radius: 50%;
116 | background-color: #e1ecff;
117 | }
118 |
119 | .sidebar-1 .material-symbols-outlined {
120 | font-size: 22px;
121 | }
122 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar2/Sidebar2.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import logo from "./logo.svg";
3 | import "./styles.css";
4 |
5 | const navItems = ["home", "settings", "build", "cloud", "mail", "bookmark"];
6 |
7 | export const Sidebar2 = () => {
8 | const [isOpen, setIsOpen] = useState(false);
9 | return (
10 |
11 |
12 |
13 |
14 | setIsOpen(!isOpen)}
18 | >
19 |
20 | {isOpen ? "close" : "menu"}
21 |
22 |
23 |
24 |
25 |
26 | {navItems.map((item) => (
27 |
28 | {item}
29 | {item}
30 |
31 | ))}
32 |
33 |
34 |
35 |
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar2/styles.css:
--------------------------------------------------------------------------------
1 | .page.sidebar-2-page {
2 | background: #17132a;
3 | }
4 |
5 | .sidebar-2 {
6 | position: absolute;
7 | overflow: hidden;
8 | top: 0;
9 | left: 0;
10 | width: 56px;
11 | height: 100%;
12 | background: #4f2cd4;
13 | transition: width 0.4s;
14 | }
15 |
16 | .sidebar-2.open {
17 | width: 260px;
18 | }
19 |
20 | .sidebar-2 .inner {
21 | position: absolute;
22 | top: 0;
23 | left: 0;
24 | width: 260px;
25 | }
26 |
27 | .sidebar-2 header {
28 | display: flex;
29 | align-items: center;
30 | height: 64px;
31 | padding: 0 6px;
32 | background: rgb(0 0 0 / 25%);
33 | }
34 |
35 | .sidebar-2-burger {
36 | width: 44px;
37 | height: 72px;
38 | display: grid;
39 | place-items: center;
40 | color: #f9f9f9;
41 | }
42 |
43 | .sidebar-2 header > img {
44 | height: 28px;
45 | }
46 |
47 | .sidebar-2 nav {
48 | display: grid;
49 | padding: 6px;
50 | gap: 2px;
51 | }
52 |
53 | .sidebar-2 nav > button {
54 | display: flex;
55 | gap: 12px;
56 | align-items: center;
57 | height: 44px;
58 | width: 44px;
59 | font-family: "Poppins";
60 | font-size: 16px;
61 | text-transform: capitalize;
62 | line-height: 1;
63 | padding: 0 12px;
64 | border-radius: 8px;
65 | color: #f9f9f9;
66 | }
67 |
68 | .sidebar-2 nav > button:hover {
69 | background: rgb(0 0 0 / 30%);
70 | }
71 |
72 | .sidebar-2 header > img,
73 | .sidebar-2 nav > button p {
74 | opacity: 0;
75 | transition: 0.3s;
76 | }
77 |
78 | .sidebar-2.open :is(nav button p, header > img) {
79 | opacity: 1;
80 | }
81 |
82 | .sidebar-2.open nav > button {
83 | width: 100%;
84 | }
85 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar3/Sidebar3.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import logo from "./logo.svg";
3 | import "./styles.css";
4 |
5 | const navItems = ["home", "settings", "build", "cloud", "mail"];
6 |
7 | export const Sidebar3 = () => {
8 | const [isOpen, setIsOpen] = useState(false);
9 | return (
10 |
11 |
12 |
13 |
14 | setIsOpen(!isOpen)}
18 | >
19 |
20 | {isOpen ? "close" : "menu"}
21 |
22 |
23 |
24 |
25 |
26 | {navItems.map((item) => (
27 |
28 | {item}
29 | {item}
30 |
31 | ))}
32 |
33 |
34 |
35 |
36 | );
37 | };
38 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar3/bg.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/sidebars/Sidebar3/bg.jpeg
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar3/styles.css:
--------------------------------------------------------------------------------
1 | .page.sidebar-3-page {
2 | background: #17132a url("./bg.jpeg");
3 | background-size: cover;
4 | }
5 |
6 | .page.sidebar-3-page::after {
7 | content: "";
8 | position: fixed;
9 | z-index: 0;
10 | inset: 0;
11 | background: rgb(0 0 0 / 15%);
12 | }
13 |
14 | .sidebar-3 {
15 | position: absolute;
16 | z-index: 2;
17 | top: 20px;
18 | left: 20px;
19 | bottom: 20px;
20 | border-radius: 8px;
21 | width: 56px;
22 | background: rgb(0 0 0 / 25%);
23 | backdrop-filter: blur(10px);
24 | transition: width 0.45s;
25 | }
26 |
27 | .sidebar-3 button {
28 | border: 0;
29 | background: transparent;
30 | cursor: pointer;
31 | }
32 |
33 | .sidebar-3 .material-symbols-outlined {
34 | font-size: 20px;
35 | }
36 |
37 | .sidebar-3.open {
38 | width: 190px;
39 | }
40 |
41 | .sidebar-3 .inner {
42 | position: absolute;
43 | top: 0;
44 | left: 0;
45 | width: 190px;
46 | }
47 |
48 | .sidebar-3 header {
49 | display: flex;
50 | align-items: center;
51 | height: 64px;
52 | border-top-left-radius: 8px;
53 | border-top-right-radius: 8px;
54 | padding: 0 6px;
55 | }
56 |
57 | .sidebar-3-burger {
58 | width: 44px;
59 | height: 72px;
60 | display: grid;
61 | place-items: center;
62 | color: #f9f9f9;
63 | }
64 |
65 | .sidebar-3 header > img {
66 | height: 18px;
67 | }
68 |
69 | .sidebar-3 nav {
70 | display: grid;
71 | padding: 0 6px;
72 | gap: 2px;
73 | }
74 |
75 | .sidebar-3 nav > button {
76 | display: flex;
77 | gap: 12px;
78 | align-items: center;
79 | height: 44px;
80 | width: 44px;
81 | font-family: "Poppins";
82 | font-size: 14px;
83 | text-transform: capitalize;
84 | line-height: 1;
85 | padding: 0 12px;
86 | border-radius: 8px;
87 | opacity: 0.7;
88 | color: #f9f9f9;
89 | }
90 |
91 | .sidebar-3 nav > button:hover {
92 | background: rgb(0 0 0 / 30%);
93 | opacity: 1;
94 | }
95 |
96 | .sidebar-3:not(.open) nav > button:hover p {
97 | opacity: 1;
98 | background: rgb(0 0 0 / 70%);
99 | padding: 4px 8px;
100 | border-radius: 6px;
101 | translate: 10px 0;
102 | }
103 |
104 | .sidebar-3 header > img,
105 | .sidebar-3 nav > button p {
106 | opacity: 0;
107 | transition: 0.25s;
108 | }
109 |
110 | .sidebar-3.open :is(nav button p, header > img) {
111 | opacity: 1;
112 | }
113 |
114 | .sidebar-3.open nav > button {
115 | width: 100%;
116 | }
117 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar4/Sidebar4.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | }
4 |
5 | .page.sidebar-4-page {
6 | background: #36367f;
7 | }
8 |
9 | .sidebar-4 button {
10 | background: transparent;
11 | border: 0;
12 | padding: 0;
13 | cursor: pointer;
14 | }
15 |
16 | .sidebar-4 {
17 | position: absolute;
18 | overflow: hidden;
19 | top: 20px;
20 | left: 20px;
21 | bottom: 30px;
22 | width: 64px;
23 | border-radius: 16px;
24 | background: #21214c;
25 | transition: width 0.4s;
26 | }
27 |
28 | .sidebar-4:hover {
29 | width: 260px;
30 | }
31 |
32 | .sidebar-4 .inner {
33 | position: absolute;
34 | top: 0;
35 | left: 0;
36 | bottom: 0;
37 | width: 260px;
38 | }
39 |
40 | .sidebar-4 .header {
41 | display: flex;
42 | align-items: center;
43 | height: 72px;
44 | padding: 0 20px;
45 | background: rgb(0 0 0 / 15%);
46 | }
47 |
48 | .sidebar-4 .header h1 {
49 | margin-left: 12px;
50 | font-weight: 500;
51 | font-size: 14px;
52 | letter-spacing: 2px;
53 | }
54 |
55 | .sidebar-4 .logo {
56 | height: 28px;
57 | scale: 1.1;
58 | transition: 0.5s;
59 | }
60 |
61 | .sidebar-4 .menu {
62 | position: relative;
63 | display: grid;
64 | }
65 |
66 | .sidebar-4 .menu::after {
67 | content: "";
68 | position: absolute;
69 | top: 0;
70 | left: 0;
71 | height: 56px;
72 | width: 6px;
73 | background: #6154f7;
74 | translate: 0 var(--top);
75 | transition: 0.5s;
76 | }
77 |
78 | .sidebar-4 .menu button {
79 | display: flex;
80 | gap: 16px;
81 | align-items: center;
82 | height: 56px;
83 | width: 100%;
84 | font-family: "Poppins";
85 | font-size: 17px;
86 | text-transform: capitalize;
87 | line-height: 1;
88 | padding: 0 22px;
89 | color: rgb(255 255 255 / 60%);
90 | cursor: pointer;
91 | opacity: 0.8;
92 | transition: 0.5s;
93 | }
94 |
95 | .sidebar-4:hover .menu button:hover:not(.active) {
96 | background: rgb(0 0 0 / 8%);
97 | }
98 |
99 | .sidebar-4 .menu :is(button:hover, .active) {
100 | background: rgb(0 0 0 / 35%);
101 | color: rgb(255 255 255 / 100%);
102 | opacity: 1;
103 | }
104 |
105 | .sidebar-4:hover .menu .active {
106 | cursor: default;
107 | }
108 |
109 | .sidebar-4 .menu button:hover > span {
110 | opacity: 1;
111 | }
112 |
113 | .sidebar-4 .menu button p,
114 | .sidebar-4 .header h1 {
115 | opacity: 0;
116 | transition: 0.5s;
117 | }
118 |
119 | .sidebar-4:hover :is(.sidebar-4 .menu button p, .sidebar-4 .header h1) {
120 | opacity: 1;
121 | }
122 |
123 | .sidebar-4:hover .logo {
124 | scale: 1;
125 | }
126 |
127 | .sidebar-4 .menu button > img {
128 | width: 24px;
129 | height: 24px;
130 | }
131 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar4/Sidebar4.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import logo from "./logo.png";
3 | import "./Sidebar4.css";
4 |
5 | const navItems = [
6 | "home",
7 | "dashboard",
8 | "mail",
9 | "cloud",
10 | "workspaces",
11 | "settings",
12 | ];
13 |
14 | export const Sidebar4 = () => {
15 | const [active, setActive] = useState(1);
16 |
17 | const goto = (index) => setActive(index);
18 |
19 | return (
20 |
21 |
22 |
23 |
24 |
25 |
Teams.co
26 |
27 |
31 | {navItems.map((item, index) => (
32 | goto(index)}
37 | >
38 | {item}
39 | {item}
40 |
41 | ))}
42 |
43 |
44 |
45 |
46 | );
47 | };
48 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar4/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/sidebars/Sidebar4/logo.png
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar5/Sidebar5.css:
--------------------------------------------------------------------------------
1 | .page.sidebar-5-page {
2 | margin: 0;
3 | background: #1c376d;
4 | height: 100vh;
5 | overflow: hidden;
6 | }
7 |
8 | .lni {
9 | font-size: 24px;
10 | }
11 |
12 | .sidebar-5 button {
13 | background: transparent;
14 | border: 0;
15 | padding: 0;
16 | cursor: pointer;
17 | }
18 |
19 | .sidebar-5 {
20 | position: absolute;
21 | overflow: hidden;
22 | top: 0;
23 | left: 0;
24 | bottom: 0;
25 | width: 260px;
26 | background: rgb(0 0 0 / 40%);
27 | }
28 |
29 | .sidebar-5 .sidebar-inner {
30 | position: absolute;
31 | top: 0;
32 | left: 0;
33 | width: 260px;
34 | }
35 |
36 | .sidebar-5 .sidebar-header {
37 | display: flex;
38 | align-items: center;
39 | height: 72px;
40 | padding-top: 10px;
41 | }
42 |
43 | .sidebar-5 .sidebar-burger {
44 | width: 60px;
45 | height: 60px;
46 | display: grid;
47 | place-items: center;
48 | color: #f9f9f9;
49 | }
50 |
51 | .sidebar-5 .sidebar-logo {
52 | height: 22px;
53 | }
54 |
55 | .sidebar-5 .sidebar-menu {
56 | display: grid;
57 | padding: 0 10px;
58 | }
59 |
60 | .sidebar-5 .sidebar-button {
61 | display: flex;
62 | gap: 16px;
63 | align-items: center;
64 | height: 56px;
65 | width: 100%;
66 | font-family: "Poppins";
67 | font-size: 17px;
68 | text-transform: capitalize;
69 | line-height: 1;
70 | padding: 0 10px;
71 | border-radius: 8px;
72 | color: #b8c2d8;
73 | opacity: 0.9;
74 | }
75 |
76 | .sidebar-5 .sidebar-button p {
77 | font-size: 15px;
78 | margin-left: 1px;
79 | }
80 |
81 | .sidebar-5 .handle {
82 | position: absolute;
83 | z-index: 100;
84 | width: 8px;
85 | top: 0;
86 | bottom: 0;
87 | right: 0;
88 | user-select: none;
89 | transition: 0.3s;
90 | }
91 |
92 | .sidebar-5 .handle:hover,
93 | .sidebar-5 .handle:active {
94 | background: rgb(255 255 255 / 6%);
95 | cursor: col-resize;
96 | }
97 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar5/Sidebar5.jsx:
--------------------------------------------------------------------------------
1 | import { useRef, useState } from "react";
2 | import logo from "./logo.svg";
3 | import "./Sidebar5.css";
4 |
5 | const items = [
6 | {
7 | name: "home",
8 | icon: "home-2",
9 | },
10 | {
11 | name: "favourites",
12 | icon: "heart",
13 | },
14 | {
15 | name: "products",
16 | icon: "cart-2",
17 | },
18 | {
19 | name: "testimonials",
20 | icon: "comment-1",
21 | },
22 | {
23 | name: "security",
24 | icon: "locked-2",
25 | },
26 | {
27 | name: "settings",
28 | icon: "gear-1",
29 | },
30 | ];
31 |
32 | const Icon = ({ children }) => ;
33 |
34 | export const Sidebar5 = () => {
35 | const [width, setWidth] = useState(60);
36 | const sidebarRef = useRef(null);
37 | const sidebar = sidebarRef.current;
38 |
39 | const resize = (e) => {
40 | let newWidth = e.clientX - sidebar?.offsetLeft;
41 | if (newWidth < 60) newWidth = 60;
42 | if (newWidth > 259) newWidth = 260;
43 | setWidth(newWidth);
44 | };
45 |
46 | const stopResize = () => {
47 | document.body.style.cursor = "default";
48 | window.removeEventListener("mousemove", resize);
49 | window.removeEventListener("mouseup", stopResize);
50 | };
51 |
52 | const initResize = () => {
53 | document.body.style.cursor = "col-resize";
54 | window.addEventListener("mousemove", resize);
55 | window.addEventListener("mouseup", stopResize);
56 | };
57 |
58 | return (
59 |
60 |
65 |
66 |
67 |
68 |
69 | menu-hamburger-1
70 |
71 |
72 |
73 |
74 | {items.map((item) => (
75 |
76 | {item.icon}
77 | {item.name}
78 |
79 | ))}
80 |
81 |
82 |
83 |
84 | );
85 | };
86 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar6/Sidebar6.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import logo from "./logo.svg";
3 | import "./Sidebar6.css";
4 |
5 | const navItems = [
6 | "dashboard",
7 | "leaderboard",
8 | "groups",
9 | "analytics",
10 | "message",
11 | "settings",
12 | ];
13 |
14 | export const Sidebar6 = () => {
15 | const [active, setActive] = useState(1);
16 |
17 | const goto = (index) => setActive(index);
18 |
19 | return (
20 |
21 |
22 |
23 |
24 |
25 |
Lampo
26 |
27 |
31 | {navItems.map((item, index) => (
32 | goto(index)}
37 | >
38 | {item}
39 | {item}
40 |
41 | ))}
42 |
43 |
44 |
45 |
46 | );
47 | };
48 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar6/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar7/Sidebar7.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import logo from "./logo.svg";
3 | import "./styles.css";
4 |
5 | const navItems = ["home", "build", "cloud", "mail", "favorite"];
6 |
7 | const Icon = ({ icon }) => (
8 | {icon}
9 | );
10 |
11 | const Button = ({ item }) => (
12 |
13 |
14 | {item}
15 |
16 | );
17 |
18 | const Header = () => (
19 |
20 |
21 |
22 | );
23 |
24 | export const Sidebar7 = () => {
25 | const [isOpen, setIsOpen] = useState(false);
26 | return (
27 |
28 | setIsOpen(!isOpen)}
32 | >
33 |
34 |
35 |
46 |
47 | );
48 | };
49 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar7/styles.css:
--------------------------------------------------------------------------------
1 | .page.sidebar-7-page {
2 | background: #1c1b23;
3 | }
4 |
5 | .page.sidebar-7-page button {
6 | background: transparent;
7 | border: 0;
8 | cursor: pointer;
9 | }
10 |
11 | .sidebar-7 {
12 | position: absolute;
13 | z-index: 1;
14 | top: 0;
15 | left: 0;
16 | bottom: 0;
17 | width: 56px;
18 | background: #5331ff;
19 | backdrop-filter: blur(10px);
20 | transition: 0.45s;
21 | }
22 |
23 | .sidebar-7 .material-symbols-outlined {
24 | font-size: 20px;
25 | }
26 |
27 | .sidebar-7.open {
28 | width: 190px;
29 | overflow: hidden;
30 | }
31 |
32 | .sidebar-7 .inner {
33 | position: absolute;
34 | top: 0;
35 | left: 0;
36 | width: 190px;
37 | height: 100%;
38 | display: flex;
39 | flex-direction: column;
40 | }
41 |
42 | .sidebar-7 header {
43 | display: flex;
44 | align-items: center;
45 | height: 64px;
46 | padding: 0 6px 0 48px;
47 | }
48 |
49 | .sidebar-7-burger {
50 | position: fixed;
51 | z-index: 2;
52 | top: 0;
53 | left: 0;
54 | width: 56px;
55 | height: 64px;
56 | display: grid;
57 | place-items: center;
58 | color: #f9f9f9;
59 | }
60 |
61 | .sidebar-7 header > img {
62 | height: 18px;
63 | }
64 |
65 | .sidebar-7 nav {
66 | display: flex;
67 | flex-direction: column;
68 | padding: 0 8px 20px;
69 | gap: 2px;
70 | flex: 1 1 auto;
71 | }
72 |
73 | .sidebar-7 nav > button {
74 | display: flex;
75 | gap: 12px;
76 | align-items: center;
77 | height: 40px;
78 | width: 40px;
79 | font-family: "Poppins";
80 | font-size: 14px;
81 | text-transform: capitalize;
82 | line-height: 1;
83 | padding: 0 10px;
84 | border-radius: 8px;
85 | color: #f9f9f9;
86 | }
87 |
88 | .sidebar-7 nav > button:last-child {
89 | margin-top: auto;
90 | }
91 |
92 | .sidebar-7 nav > button:hover {
93 | background: rgb(0 0 0 / 24%);
94 | }
95 |
96 | .sidebar-7:not(.open) nav p {
97 | visibility: hidden;
98 | }
99 |
100 | .sidebar-7:not(.open) nav > button:hover p {
101 | opacity: 1;
102 | visibility: visible;
103 | background: #2e2a47;
104 | padding: 5px 10px;
105 | font-size: 13px;
106 | border-radius: 6px;
107 | translate: 12px 0;
108 | }
109 |
110 | .sidebar-7 header > img,
111 | .sidebar-7 nav > button p {
112 | opacity: 0;
113 | transition: 0.25s;
114 | }
115 |
116 | .sidebar-7.open :is(nav button p, header > img) {
117 | opacity: 1;
118 | }
119 |
120 | .sidebar-7.open nav > button {
121 | width: 100%;
122 | }
123 |
124 | @media (width <= 400px) {
125 | .sidebar-7 {
126 | translate: -100% 0;
127 | }
128 |
129 | .sidebar-7.open {
130 | translate: 0;
131 | }
132 |
133 | .sidebar-7:not(.open) button span {
134 | transition: 0.3s;
135 | opacity: 0;
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar8/Sidebar8 copy.css:
--------------------------------------------------------------------------------
1 | .sidebar-8 header :is(h2, h3) {
2 | margin: 0;
3 | }
4 |
5 | .sidebar-8 {
6 | --color-hover: #313132;
7 | --border: 1px solid #2d2d2d;
8 | position: fixed;
9 | overflow: hidden;
10 | top: 24px;
11 | left: 24px;
12 | bottom: 28px;
13 | display: flex;
14 | flex-direction: column;
15 | gap: 8px;
16 | width: 80px;
17 | border-radius: 18px;
18 | border: var(--border);
19 | transition: 0.4s;
20 | background: #1c1c1c;
21 | }
22 |
23 | .sidebar-8 button {
24 | border: 0;
25 | background: transparent;
26 | font-size: 22px;
27 | color: inherit;
28 | border-radius: 8px;
29 | font-family: inherit;
30 | cursor: pointer;
31 | transition: 0.3s;
32 | }
33 |
34 | .sidebar-8-left,
35 | .sidebar-8-right {
36 | position: absolute;
37 | top: 0;
38 | bottom: 0;
39 | transition: 0.4s;
40 | display: flex;
41 | flex-direction: column;
42 | align-items: center;
43 | }
44 |
45 | .sidebar-8-left {
46 | z-index: 1;
47 | left: 0;
48 | width: 80px;
49 | }
50 |
51 | .sidebar-8-dots {
52 | position: absolute;
53 | top: 10px;
54 | left: 18px;
55 | width: 10px;
56 | height: 10px;
57 | border-radius: 50%;
58 | background: #ee6c5f;
59 | }
60 |
61 | .sidebar-8-dots::before,
62 | .sidebar-8-dots::after {
63 | content: "";
64 | width: inherit;
65 | height: inherit;
66 | border-radius: inherit;
67 | position: inherit;
68 | }
69 |
70 | .sidebar-8-dots::before {
71 | left: 16px;
72 | background: #f7bc50;
73 | }
74 |
75 | .sidebar-8-dots::after {
76 | left: 32px;
77 | background: #61c453;
78 | }
79 |
80 | .sidebar-8-left img {
81 | width: 40px;
82 | margin: 36px 0 14px;
83 | }
84 |
85 | .sidebar-8-left button {
86 | width: 44px;
87 | height: 44px;
88 | display: grid;
89 | place-items: center;
90 | opacity: 0.8;
91 | }
92 |
93 | .sidebar-8-left button:hover {
94 | opacity: 1;
95 | background: var(--color-hover);
96 | }
97 |
98 | .sidebar-8-left div:last-of-type {
99 | margin-top: auto;
100 | margin-bottom: 16px;
101 | }
102 |
103 | .sidebar-8-right {
104 | left: 76px;
105 | height: 100%;
106 | position: relative;
107 | }
108 |
109 | .sidebar-8-right-inner {
110 | position: absolute;
111 | inset: 8px;
112 | left: 6px;
113 | border-radius: 12px;
114 | background: #1a1a1a;
115 | border: var(--border);
116 | }
117 |
118 | .sidebar-8-right header {
119 | display: flex;
120 | align-items: center;
121 | justify-content: space-between;
122 | padding: 30px 16px 18px;
123 | }
124 |
125 | .sidebar-8-right h2 {
126 | font-size: 16px;
127 | font-weight: 600;
128 | }
129 |
130 | .sidebar-8-right h3 {
131 | font-size: 12px;
132 | font-weight: 500;
133 | color: #7e7f82;
134 | }
135 |
136 | .sidebar-8-right nav {
137 | padding: 0 12px;
138 | }
139 |
140 | .sidebar-8-right button {
141 | padding: 0 12px;
142 | background: transparent;
143 | display: flex;
144 | align-items: center;
145 | gap: 10px;
146 | width: 100%;
147 | height: 44px;
148 | font-size: 15px;
149 | opacity: 0.7;
150 | }
151 |
152 | .sidebar-8-right button:hover {
153 | opacity: 1;
154 | background: var(--color-hover);
155 | }
156 |
157 | .sidebar-8-right button i {
158 | font-size: 18px;
159 | }
160 |
161 | .sidebar-8:hover {
162 | width: 300px;
163 | }
164 |
165 | .sidebar-8:hover .sidebar-8-right {
166 | width: 225px;
167 | }
168 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar8/Sidebar8.jsx:
--------------------------------------------------------------------------------
1 | import logo from "./logo.svg";
2 | import "./Sidebar8.css";
3 |
4 | const navItems = ["home-alt1", "heart", "mention", "plus"];
5 |
6 | const footerItems = ["gear", "link-out"];
7 |
8 | const innerItems = [
9 | {
10 | name: "Dashboard",
11 | icon: "dashboard",
12 | },
13 | {
14 | name: "Products",
15 | icon: "shipping-box-v1",
16 | },
17 | {
18 | name: "Customers",
19 | icon: "person",
20 | },
21 | {
22 | name: "Messages",
23 | icon: "open-envelope",
24 | },
25 | {
26 | name: "Images",
27 | icon: "image",
28 | },
29 | {
30 | name: "Inventory",
31 | icon: "data",
32 | },
33 | {
34 | name: "Hashtags",
35 | icon: "hashtag",
36 | },
37 | ];
38 |
39 | const Icon = ({ icon }) => ;
40 |
41 | const Button = ({ item }) => (
42 |
43 |
44 | {item.name}
45 |
46 | );
47 |
48 | const Header = () => (
49 |
56 | );
57 |
58 | export const Sidebar8 = () => {
59 | return (
60 |
90 | );
91 | };
92 |
--------------------------------------------------------------------------------
/src/components/sidebars/Sidebar8/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/components/sidebars/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Sidebar1/Sidebar1";
2 | export * from "./Sidebar2/Sidebar2";
3 | export * from "./Sidebar3/Sidebar3";
4 | export * from "./Sidebar4/Sidebar4";
5 | export * from "./Sidebar5/Sidebar5";
6 | export * from "./Sidebar6/Sidebar6";
7 | export * from "./Sidebar7/Sidebar7";
8 | export * from "./Sidebar8/Sidebar8";
9 |
--------------------------------------------------------------------------------
/src/components/signups/index.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/frontend-joe/react-components/7addf3d8106d807f5013ba8e2942f4d51e60d20c/src/components/signups/index.js
--------------------------------------------------------------------------------
/src/components/tables/Table1/Table1.css:
--------------------------------------------------------------------------------
1 | .table-1-wrapper {
2 | overflow: auto;
3 | position: relative;
4 | z-index: 2;
5 | width: 440px;
6 | min-width: 440px;
7 | max-width: 440px;
8 | }
9 |
10 | .table-1-card table {
11 | width: 100%;
12 | border-collapse: collapse;
13 | text-align: left;
14 | }
15 |
16 | .table-1-card table th {
17 | opacity: 0.5;
18 | font-weight: 400;
19 | user-select: none;
20 | text-transform: capitalize;
21 | background: rgb(255 255 255 / 6%);
22 | }
23 |
24 | .table-1-card table :is(th, td) {
25 | position: relative;
26 | overflow: hidden;
27 | white-space: nowrap;
28 | height: 36px;
29 | padding: 0 10px;
30 | border: 1px solid rgb(255 255 255 / 10%);
31 | }
32 |
33 | .table-1-card table th .draggable {
34 | position: absolute;
35 | top: 0;
36 | right: 0;
37 | bottom: 0;
38 | width: 6px;
39 | cursor: col-resize;
40 | }
41 |
--------------------------------------------------------------------------------
/src/components/tables/Table1/Table1.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useRef, useState, createRef } from "react";
2 | import "./Table1.css";
3 |
4 | const TableHeader = ({ index, column, columnRef, initResize }) => {
5 | const width = !!initResize ? column.width : "100%";
6 |
7 | return (
8 |
16 | {column.name}
17 | {!!initResize && (
18 | initResize(e, index)}
21 | >
22 | )}
23 |
24 | );
25 | };
26 |
27 | export const Table1 = ({ columns, data }) => {
28 | const [columnState, setColumnState] = useState(columns);
29 | const [columnRefs, setColumnRefs] = useState([]);
30 |
31 | const wrapperRef = useRef(null);
32 | const activeIndex = useRef(null);
33 |
34 | const resize = (e) => {
35 | const columnsCopy = [...columns];
36 | const column = columnsCopy[activeIndex.current];
37 | const columnRef = columnRefs[activeIndex.current];
38 | const nextWidth =
39 | e.clientX -
40 | 48 -
41 | columnRef.current.offsetLeft -
42 | (wrapperRef.current.offsetLeft - wrapperRef.current.scrollLeft);
43 |
44 | console.log("nextWidth", nextWidth);
45 |
46 | column.width = nextWidth;
47 |
48 | setColumnState(columnsCopy);
49 | };
50 |
51 | const stopResize = () => {
52 | document.body.style.cursor = "default";
53 | window.removeEventListener("mousemove", resize);
54 | window.removeEventListener("mouseup", stopResize);
55 | };
56 |
57 | const initResize = (e, index) => {
58 | activeIndex.current = index;
59 | e.stopPropagation();
60 | document.body.style.cursor = "col-resize";
61 | window.addEventListener("mousemove", resize);
62 | window.addEventListener("mouseup", stopResize);
63 | };
64 |
65 | useEffect(() => {
66 | setColumnRefs(
67 | Array(columns.length)
68 | .fill()
69 | .map((_, i) => columnRefs[i] || createRef())
70 | );
71 | }, []);
72 |
73 | return (
74 |
75 |
76 |
77 |
78 | {columnState.map((column, index) => (
79 |
88 | ))}
89 |
90 |
91 |
92 | {data.map((item) => (
93 |
94 | {columnState.map((column) => (
95 |
96 | {item[column.name]}
97 |
98 | ))}
99 |
100 | ))}
101 |
102 |
103 |
104 |
105 | );
106 | };
107 |
--------------------------------------------------------------------------------
/src/components/tables/Table1/Table1Example.css:
--------------------------------------------------------------------------------
1 | .page.table-1-page {
2 | background: linear-gradient(45deg, #2c3c5e, #1a2239);
3 | color: #f9f9f9;
4 | display: flex;
5 | align-items: flex-start;
6 | display: grid;
7 | place-items: center;
8 | }
9 |
10 | .table-1-card {
11 | background: rgb(255 255 255 / 3%);
12 | border: 2px solid rgb(255 255 255 / 3%);
13 | backdrop-filter: blur(10px);
14 | border-radius: 12px;
15 | padding: 24px;
16 | font-size: 12px;
17 | }
18 |
19 | .table-1-card .header {
20 | display: flex;
21 | justify-content: space-between;
22 | margin-bottom: 24px;
23 | }
24 |
25 | .table-1-card .header h2 {
26 | font-weight: 400;
27 | opacity: 0.6;
28 | display: flex;
29 | align-items: center;
30 | }
31 |
32 | .table-1-card .header button {
33 | background: #2e5fdc;
34 | color: rgb(255 255 255 / 96%);
35 | font-size: 12px;
36 | border: 0;
37 | border-radius: 20px;
38 | font-family: inherit;
39 | padding: 8px 14px;
40 | }
41 |
--------------------------------------------------------------------------------
/src/components/tables/Table1/Table1Example.jsx:
--------------------------------------------------------------------------------
1 | import { Table1 } from "./Table1";
2 | import "./Table1Example.css";
3 | import logo from "./logo.svg";
4 |
5 | const columns = [
6 | {
7 | name: "name",
8 | width: 125,
9 | },
10 | {
11 | name: "age",
12 | width: 50,
13 | },
14 | {
15 | name: "level",
16 | width: 170,
17 | },
18 | ];
19 |
20 | const data = [
21 | {
22 | name: "Alice Johnson",
23 | age: 29,
24 | level: "Intermediate",
25 | languages: ["Python", "JavaScript", "HTML"],
26 | },
27 | {
28 | name: "Bob Smith",
29 | age: 35,
30 | level: "Advanced",
31 | languages: ["Java", "Kotlin", "Scala"],
32 | },
33 | {
34 | name: "Charlie Evans",
35 | age: 23,
36 | level: "Beginner",
37 | languages: ["Python", "C++"],
38 | },
39 | {
40 | name: "Diana Lee",
41 | age: 41,
42 | level: "Expert",
43 | languages: ["C#", "F#", "SQL"],
44 | },
45 | {
46 | name: "Edward Kim",
47 | age: 28,
48 | level: "Intermediate",
49 | languages: ["JavaScript", "TypeScript", "Node.js"],
50 | },
51 | {
52 | name: "Fiona Garcia",
53 | age: 32,
54 | level: "Advanced",
55 | languages: ["Ruby", "Go", "Elixir"],
56 | },
57 | {
58 | name: "George Thompson",
59 | age: 26,
60 | level: "Intermediate",
61 | languages: ["PHP", "Python", "JavaScript"],
62 | },
63 | ];
64 |
65 | export const Table1Example = () => {
66 | return (
67 |
68 |
69 |
70 |
Developers
71 | Download
72 |
73 |
74 |
75 |
76 | );
77 | };
78 |
--------------------------------------------------------------------------------
/src/components/tables/Table1/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/components/tables/Table2/Table2.css:
--------------------------------------------------------------------------------
1 | .table-2 {
2 | border-collapse: collapse;
3 | text-align: left;
4 | width: 100%;
5 | }
6 |
7 | .table-2 thead {
8 | position: sticky;
9 | top: 0;
10 | left: 0;
11 | z-index: 1;
12 | }
13 |
14 | .table-2 thead tr th:not(:last-child) {
15 | width: 120px;
16 | max-width: 120px;
17 | }
18 |
19 | .table-2 :is(th, td) {
20 | position: relative;
21 | overflow: hidden;
22 | white-space: nowrap;
23 | padding: 0 6px;
24 | height: 50px;
25 | font-size: 13px;
26 | }
27 |
28 | .table-2 th {
29 | font-weight: 500;
30 | user-select: none;
31 | text-transform: capitalize;
32 | color: #706d84;
33 | height: 56px;
34 | cursor: pointer;
35 | vertical-align: middle;
36 | transition: 0.3s;
37 | }
38 |
39 | .table-2 th i {
40 | font-size: 11px;
41 | translate: 0 -1px;
42 | margin-left: 6px;
43 | }
44 |
45 | .table-2 th:is(.active, :hover) {
46 | color: inherit;
47 | }
48 |
49 | .table-2 td {
50 | opacity: 0.65;
51 | transition: opacity 0.3s;
52 | }
53 |
54 | .table-2 tbody tr:hover td {
55 | opacity: 1;
56 | }
57 |
58 | .table-2 tr {
59 | cursor: pointer;
60 | border-bottom: 1px solid #34323c;
61 | }
62 |
63 | .table-2 tbody tr:last-child {
64 | border: 0;
65 | }
66 |
67 | .table-2 tbody tr:nth-child(odd) {
68 | background: #1e1d25;
69 | }
70 |
--------------------------------------------------------------------------------
/src/components/tables/Table2/Table2.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./Table2.css";
3 |
4 | const TableHeader = ({ column, onSort, sortOrder, sortColumn }) => {
5 | const isActive = column === sortColumn;
6 | return (
7 | onSort(column)}>
8 | {column}
9 | {isActive && (
10 |
13 | )}
14 |
15 | );
16 | };
17 |
18 | export const Table2 = ({ rows, columns }) => {
19 | const [sortColumn, setSortColumn] = useState(columns[0]);
20 | const [sortOrder, setSortOrder] = useState("asc");
21 |
22 | const sortedRows = rows.sort((a, b) => {
23 | const [valA, valB] = [a[sortColumn], b[sortColumn]];
24 | return typeof valA === typeof valB
25 | ? sortOrder === "asc"
26 | ? valA > valB
27 | ? 1
28 | : -1
29 | : valA < valB
30 | ? 1
31 | : -1
32 | : 0;
33 | });
34 |
35 | const handleSort = (column) => {
36 | console.log("name", column);
37 | setSortColumn(column);
38 | setSortOrder(
39 | sortColumn !== column ? "asc" : sortOrder === "asc" ? "desc" : "asc"
40 | );
41 | };
42 |
43 | return (
44 |
45 |
46 |
47 | {columns.map((column) => (
48 |
55 | ))}
56 |
57 |
58 |
59 | {sortedRows.map((row) => (
60 |
61 | {columns.map((column) => (
62 | {row[column]}
63 | ))}
64 |
65 | ))}
66 |
67 |
68 | );
69 | };
70 |
--------------------------------------------------------------------------------
/src/components/tables/Table2/Table2Example.css:
--------------------------------------------------------------------------------
1 | .table-2-page {
2 | background: #222129;
3 | color: #f5f3f9;
4 | margin: 0;
5 | height: 100vh;
6 | font-size: 110%;
7 | font-family: "Euclid Circular A", "Poppins";
8 | }
9 |
10 | .table-2-page .wrapper {
11 | overflow: auto;
12 | position: relative;
13 | z-index: 2;
14 | }
15 |
16 | .table-2-page header {
17 | position: relative;
18 | overflow: hidden;
19 | margin: 0 0 18px;
20 | }
21 |
22 | .table-2-page header .content {
23 | position: relative;
24 | z-index: 1;
25 | display: flex;
26 | align-items: center;
27 | justify-content: space-between;
28 | height: 240px;
29 | max-width: 700px;
30 | margin: 0 auto;
31 | padding: 0 70px 60px;
32 | }
33 |
34 | .table-2-page header::before {
35 | content: "";
36 | position: absolute;
37 | bottom: 0;
38 | left: 50%;
39 | translate: -50% 0;
40 | z-index: 0;
41 | background: #5926fc;
42 | width: 500vw;
43 | aspect-ratio: 1/1;
44 | border-radius: 50%;
45 | }
46 |
47 | .table-2-page header button {
48 | font-family: inherit;
49 | background: rgb(0 0 0 / 16%);
50 | color: inherit;
51 | border: 0;
52 | border-radius: 8px;
53 | padding: 12px 18px 12px 20px;
54 | font-size: 13.5px;
55 | display: flex;
56 | align-items: center;
57 | gap: 4px;
58 | }
59 |
60 | .table-2-page header button span {
61 | font-size: 16px;
62 | translate: 0 -1px;
63 | }
64 |
65 | .table-2-page header h2 {
66 | font-size: 20px;
67 | font-weight: 400;
68 | display: flex;
69 | align-items: center;
70 | }
71 |
72 | .table-2-page header h2 i {
73 | margin-right: 8px;
74 | background: rgb(0 0 0 / 16%);
75 | display: grid;
76 | place-items: center;
77 | width: 40px;
78 | height: 40px;
79 | border-radius: 8px;
80 | }
81 |
82 | .table-2-page .card {
83 | max-width: 600px;
84 | margin: 0 auto;
85 | position: relative;
86 | z-index: 1;
87 | background: #1a191e;
88 | border-radius: 8px;
89 | box-shadow: 0 30px 40px rgb(0 0 0 / 12%);
90 | padding: 10px 18px 18px;
91 | font-size: 12px;
92 | margin: -100px auto 30px;
93 | }
94 |
95 | @media (width < 706px) {
96 | .table-2-page .card {
97 | margin: -100px 50px 30px;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/src/components/tables/Table2/Table2Example.jsx:
--------------------------------------------------------------------------------
1 | import { Table2 } from "./Table2";
2 | import "./Table2Example.css";
3 |
4 | const rows = [
5 | {
6 | name: "Zoe Blogs",
7 | level: "Intermediate",
8 | age: 21,
9 | language: "JavaScript",
10 | location: "USA",
11 | },
12 | {
13 | name: "Jane Doe",
14 | level: "Advanced",
15 | age: 25,
16 | language: "Python",
17 | location: "Canada",
18 | },
19 | {
20 | name: "Alice Smith",
21 | level: "Junior",
22 | age: 22,
23 | language: "Ruby",
24 | location: "UK",
25 | },
26 | {
27 | name: "Bob Kohler",
28 | level: "Senior",
29 | age: 35,
30 | language: "C#",
31 | location: "Germany",
32 | },
33 | {
34 | name: "Dana White",
35 | level: "Junior",
36 | age: 23,
37 | language: "PHP",
38 | location: "France",
39 | },
40 | {
41 | name: "Ethan Hunt",
42 | level: "Advanced",
43 | age: 28,
44 | language: "JavaScript",
45 | location: "USA",
46 | },
47 | {
48 | name: "Fiona Green",
49 | level: "Senior",
50 | age: 40,
51 | language: "Java",
52 | location: "Ireland",
53 | },
54 | {
55 | name: "Luuk Black",
56 | level: "Intermediate",
57 | age: 30,
58 | language: "JavaScript",
59 | location: "Netherlands",
60 | },
61 | {
62 | name: "Hannah Isak",
63 | level: "Junior",
64 | age: 24,
65 | language: "Kotlin",
66 | location: "Sweden",
67 | },
68 | ];
69 |
70 | const columns = ["name", "level", "language", "location"];
71 |
72 | export const Table2Example = () => {
73 | return (
74 |
101 | );
102 | };
103 |
--------------------------------------------------------------------------------
/src/components/tables/Table3/Table3.css:
--------------------------------------------------------------------------------
1 | .table-3 {
2 | width: 100%;
3 | border-collapse: collapse;
4 | }
5 |
6 | .table-3 td {
7 | padding: 16px;
8 | white-space: nowrap;
9 | }
10 |
11 | .table-3 tr td:last-of-type {
12 | text-align: right;
13 | }
14 |
15 | .table-3 th:first-of-type {
16 | width: 20px;
17 | }
18 |
19 | .table-3 tr td:first-child,
20 | .table-3 tr th:first-child {
21 | padding-right: 2px;
22 | }
23 |
24 | .table-3 tr td:last-child,
25 | .table-3 tr th:last-child {
26 | padding-right: 12px;
27 | }
28 |
29 | .table-3 th:nth-child(2) {
30 | width: 133px;
31 | max-width: 133px;
32 | min-width: 133px;
33 | }
34 |
35 | .table-3 th:nth-child(3) {
36 | width: 180px;
37 | max-width: 180px;
38 | min-width: 180px;
39 | }
40 |
41 | .table-3 th {
42 | padding: 20px 16px;
43 | font-weight: 500;
44 | text-align: left;
45 | text-transform: capitalize;
46 | }
47 |
48 | .table-3 :is(td, th) {
49 | border-bottom: 1px solid #2d2d2d;
50 | }
51 |
52 | .table-3-footer {
53 | display: flex;
54 | align-items: center;
55 | }
56 |
57 | .table-3-footer p {
58 | margin: 0;
59 | font-size: 14px;
60 | color: #8a8a8a;
61 | }
62 |
63 | .table-3-footer p em {
64 | color: #ffffff;
65 | font-style: normal;
66 | }
67 |
68 | .table-3-pagination {
69 | padding: 16px;
70 | display: flex;
71 | }
72 |
73 | .table-3-pagination > button {
74 | background: transparent;
75 | border: 1px solid #2d2d2d;
76 | border-right: 0;
77 | color: #ffffff;
78 | font-family: inherit;
79 | padding: 0 12px;
80 | display: flex;
81 | align-items: center;
82 | justify-content: center;
83 | height: 40px;
84 | width: 40px;
85 | font-size: 14px;
86 | transition: 0.3s;
87 | }
88 |
89 | .table-3-pagination > button:first-child {
90 | border-top-left-radius: 6px;
91 | border-bottom-left-radius: 6px;
92 | }
93 |
94 | .table-3-pagination > button:last-child {
95 | border-top-right-radius: 6px;
96 | border-bottom-right-radius: 6px;
97 | border-right: 1px solid #2d2d2d;
98 | }
99 |
100 | .table-3-pagination > button:hover {
101 | background: rgb(255 255 255 / 1%);
102 | }
103 |
104 | .table-3-pagination > button.active {
105 | background: #2d2d2d;
106 | }
107 |
--------------------------------------------------------------------------------
/src/components/tables/Table3/Table3.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./Table3.css";
3 | import { Checkbox } from "./Table3Example";
4 |
5 | const pageSize = 5;
6 |
7 | const PaginatedTable = ({ pageNumber, totalPages, totalRows, goToPage }) => {
8 | return (
9 |
10 |
11 | {[...Array(totalPages)].map((_, index) => (
12 | goToPage(index + 1)}
15 | disabled={pageNumber === index + 1}
16 | className={pageNumber === index + 1 ? "active" : ""}
17 | >
18 | {index + 1}
19 |
20 | ))}
21 |
22 |
23 | Viewing{" "}
24 |
25 | {pageNumber === 1 ? 1 : (pageNumber - 1) * pageSize + 1}-
26 | {pageNumber * pageSize}
27 | {" "}
28 | of {totalRows} rows
29 |
30 |
31 | );
32 | };
33 |
34 | export const Table3 = ({ columns, rows }) => {
35 | const [pageNumber, setPageNumber] = useState(1);
36 |
37 | const totalPages = Math.ceil(rows.length / pageSize);
38 |
39 | const paginateArray = (array, pageSize, pageNumber) => {
40 | return array.slice((pageNumber - 1) * pageSize, pageNumber * pageSize);
41 | };
42 |
43 | const goToPage = (page) => setPageNumber(page);
44 |
45 | return (
46 | <>
47 |
48 |
49 |
50 |
51 |
52 |
53 | {columns.map((column, index) => (
54 | {column}
55 | ))}
56 |
57 |
58 |
59 | {paginateArray(rows, pageSize, pageNumber).map((row, index) => (
60 |
61 | {row.map((control, index) => (
62 | {control}
63 | ))}
64 |
65 | ))}
66 |
67 |
68 |
74 | >
75 | );
76 | };
77 |
--------------------------------------------------------------------------------
/src/components/tables/Table3/image.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/components/tables/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Table1/Table1Example";
2 | export * from "./Table2/Table2Example";
3 | export * from "./Table3/Table3Example";
4 |
--------------------------------------------------------------------------------
/src/components/widgets/Widget1/Widget1.jsx:
--------------------------------------------------------------------------------
1 | import { createRef, useEffect, useState } from "react";
2 | import "./styles.css";
3 |
4 | const buttonWidth = 56;
5 | const tabWidth = 300;
6 |
7 | const tabs = [
8 | {
9 | title: "Home",
10 | icon: "home",
11 | content:
12 | "Some information inside the tab widget, that will auto resize it's height.",
13 | },
14 | {
15 | title: "Settings",
16 | icon: "settings",
17 | content:
18 | "Some information inside the tab widget, that will auto resize it's height. This one has extra information so is a bit taller. Let's add one more sentence to see it's height grow even more!",
19 | },
20 | {
21 | title: "Account",
22 | icon: "lock",
23 | content:
24 | "Some information inside the tab widget, that will auto resize it's height. This one has extra information so is a bit taller. ",
25 | },
26 | ];
27 |
28 | const WidgetHeader = ({ onClick, activeIndex }) => {
29 | return (
30 |
31 | {tabs.map((tab, index) => (
32 | onClick(index)}
34 | key={tab.title}
35 | className={`material-symbols-outlined ${
36 | activeIndex === index ? "active" : ""
37 | }`}
38 | >
39 | {tab.icon}
40 |
41 | ))}
42 |
48 |
49 | );
50 | };
51 |
52 | const WidgetTab = ({ tabRef, title, content }) => {
53 | return (
54 |
55 |
{title}
56 |
{content}
57 |
58 | );
59 | };
60 |
61 | export const Widget1 = () => {
62 | const [activeIndex, setActiveIndex] = useState(0);
63 |
64 | const [height, setHeight] = useState(140);
65 |
66 | const [refs, setRefs] = useState([]);
67 |
68 | const handleClick = (index) => {
69 | setActiveIndex(index);
70 | setHeight(refs[index].current.clientHeight);
71 | };
72 |
73 | useEffect(() => {
74 | setRefs(tabs.map(() => createRef()));
75 | }, []);
76 |
77 | useEffect(() => {
78 | if (!refs.length) return;
79 | setHeight(refs[0].current.clientHeight);
80 | }, [refs.length]);
81 |
82 | return (
83 |
84 |
85 |
86 |
92 | {tabs.map((tab, index) => (
93 |
99 | ))}
100 |
101 |
102 |
103 | );
104 | };
105 |
106 | export const Widget1Example = () => (
107 |
110 | );
111 |
--------------------------------------------------------------------------------
/src/components/widgets/Widget1/styles.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --color-primary: #5644fd;
3 | --tab-width: 300px;
4 | --button-width: 56px;
5 | }
6 |
7 | .page.widget-1-page {
8 | display: flex;
9 | flex-direction: column;
10 | justify-content: start;
11 | padding-top: 260px;
12 | font-family: "Euclid Circular A", "Poppins";
13 | line-height: 1.5;
14 | background: #24232b;
15 | color: #f9f9f9;
16 | }
17 |
18 | .widget {
19 | background: #18181d;
20 | width: var(--tab-width);
21 | border-radius: 8px;
22 | }
23 |
24 | .widget h2 {
25 | margin: 0;
26 | }
27 |
28 | .widget > header {
29 | position: relative;
30 | display: flex;
31 | border-bottom: 1px solid rgb(255 255 255 / 10%);
32 | }
33 |
34 | .widget > header > button {
35 | padding: 20px 0;
36 | font-size: 15px;
37 | width: var(--button-width);
38 | cursor: pointer;
39 | background: transparent;
40 | color: rgb(255 255 255 / 50%);
41 | display: grid;
42 | place-items: center;
43 | border: 0;
44 | font-size: 22px;
45 | transition: 0.5s;
46 | }
47 |
48 | .widget > header > button:not(.active) {
49 | opacity: 0.7;
50 | }
51 |
52 | .widget > header > button:hover:not(.active) {
53 | opacity: 1;
54 | }
55 |
56 | .widget > header > button.active {
57 | color: var(--color-primary);
58 | }
59 |
60 | .widget .content {
61 | position: relative;
62 | overflow: hidden;
63 | transition: 0.5s;
64 | }
65 |
66 | .widget .content-inner {
67 | position: absolute;
68 | top: 0;
69 | left: 0;
70 | display: flex;
71 | align-items: start;
72 | width: calc(var(--tab-width) * 3);
73 | transition: 0.5s;
74 | }
75 |
76 | .widget .underline {
77 | position: absolute;
78 | left: 0;
79 | bottom: 0;
80 | width: var(--button-width);
81 | height: 3px;
82 | background: var(--color-primary);
83 | transition: 0.2s;
84 | }
85 |
86 | .widget h2 {
87 | margin: 0 0 10px;
88 | font-size: 15px;
89 | font-weight: 400;
90 | }
91 |
92 | .widget p {
93 | margin: 0;
94 | font-size: 13px;
95 | opacity: 0.5;
96 | }
97 |
98 | .widget .content-inner > div {
99 | width: inherit;
100 | padding: 20px;
101 | }
102 |
--------------------------------------------------------------------------------
/src/components/widgets/Widget2/Widget2.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./styles.css";
3 |
4 | const menuHeight = getComputedStyle(document.body).getPropertyValue(
5 | "--widget-2-menu-height"
6 | );
7 |
8 | const items = [
9 | {
10 | name: "Home",
11 | content:
12 | "Vivamus volutpat ipsum ac ipsum feugiat, vel molestie elit vestibulum. Donec luctus commodo dictum. Aenean in turpis erat. Vestibulum imperdiet nibh. Ipsum ac ipsum feugiat, vel molestie.",
13 | },
14 | {
15 | name: "Security",
16 | icon: "Encrypted",
17 | content:
18 | "Vivamus volutpat ipsum ac ipsum feugiat, vel molestie elit vestibulum. Donec luctus commodo dictum. Aenean in turpis erat. Vestibulum imperdiet nibh. Ipsum ac ipsum feugiat, vel molestie.",
19 | },
20 | {
21 | name: "Stacks",
22 | content:
23 | "Vivamus volutpat ipsum ac ipsum feugiat, vel molestie elit vestibulum. Donec luctus commodo dictum. Aenean in turpis erat. Vestibulum imperdiet nibh. Ipsum ac ipsum feugiat, vel molestie.",
24 | },
25 | {
26 | name: "Settings",
27 | content:
28 | "Vivamus volutpat ipsum ac ipsum feugiat, vel molestie elit vestibulum. Donec luctus commodo dictum. Aenean in turpis erat. Vestibulum imperdiet nibh. Ipsum ac ipsum feugiat, vel molestie.",
29 | },
30 | ];
31 |
32 | export const Widget2 = () => {
33 | const [activeBlock, setActiveBlock] = useState(0);
34 |
35 | const toggleMenuBlock = (index) => setActiveBlock(index);
36 |
37 | return (
38 |
39 |
40 |
41 | {items.map((item, index) => (
42 | toggleMenuBlock(index)}
46 | >
47 |
48 | {item.icon || item.name}
49 |
50 | {item.name}
51 |
52 | ))}
53 |
54 |
55 |
61 | {items.map((item) => (
62 |
63 |
{item.name}
64 |
{item.content}
65 |
66 | ))}
67 |
68 |
69 |
70 |
71 | );
72 | };
73 |
--------------------------------------------------------------------------------
/src/components/widgets/Widget2/styles copy.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --widget-2-color-primary: #195adc;
3 | --widget-2-sidebar-width: 130px;
4 | --widget-2-menu-height: 200px;
5 | }
6 |
7 | .page.widget-2-page {
8 | margin: 0;
9 | display: grid;
10 | place-items: center;
11 | background: linear-gradient(-135deg, var(--widget-2-color-primary), #0f3278);
12 | color: #f0f5ff;
13 | }
14 |
15 | .widget-2-card {
16 | display: flex;
17 | padding: 0 20px;
18 | width: 440px;
19 | height: var(--widget-2-menu-height);
20 | border-radius: 10px;
21 | background: #101115;
22 | box-shadow: 0 20px 30px rgba(57, 76, 96, 0.06);
23 | }
24 |
25 | .widget-2-card .buttons {
26 | padding-top: 20px;
27 | width: var(--widget-2-sidebar-width);
28 | }
29 |
30 | .widget-2-card .buttons button {
31 | margin: 0;
32 | font-size: 14px;
33 | width: 100%;
34 | height: 40px;
35 | padding: 0 0 0 12px;
36 | background: transparent;
37 | border-radius: 6px;
38 | border: 0;
39 | display: flex;
40 | gap: 8px;
41 | align-items: center;
42 | font-weight: 400;
43 | font-family: inherit;
44 | cursor: pointer;
45 | color: inherit;
46 | }
47 |
48 | .widget-2-card .buttons button:focus {
49 | outline-color: var(--widget-2-color-primary);
50 | outline-offset: 0;
51 | }
52 |
53 | .widget-2-card .buttons button:hover {
54 | background-color: rgb(255 255 255 / 4%);
55 | }
56 |
57 | .widget-2-card .buttons button span {
58 | font-size: 16px;
59 | }
60 |
61 | .widget-2-card .buttons button.active {
62 | background: var(--widget-2-color-primary);
63 | color: #f9f9f9;
64 | }
65 |
66 | .widget-2-card .wrapper {
67 | position: relative;
68 | overflow: hidden;
69 | flex: 1 1 auto;
70 | }
71 |
72 | .widget-2-card .wrapper::before,
73 | .widget-2-card .wrapper::after {
74 | content: "";
75 | position: absolute;
76 | z-index: 2;
77 | left: 0;
78 | width: 100%;
79 | height: 36px;
80 | }
81 |
82 | .widget-2-card .wrapper::before {
83 | top: 0;
84 | background: linear-gradient(#101115, rgb(24 24 29 / 0%));
85 | }
86 |
87 | .widget-2-card .wrapper::after {
88 | bottom: 0;
89 | background: linear-gradient(rgb(24 24 29 / 0%), #101115);
90 | }
91 |
92 | .widget-2-card .content {
93 | position: absolute;
94 | z-index: 1;
95 | top: 0;
96 | left: 0;
97 | height: calc(var(--widget-2-menu-height) * 3);
98 | transition: 0.6s;
99 | }
100 |
101 | .widget-2-card .content p {
102 | display: flex;
103 | align-items: center;
104 | line-height: 1.6;
105 | font-size: 13px;
106 | margin: 0;
107 | opacity: 0.5;
108 | }
109 |
110 | .widget-2-card .block {
111 | display: flex;
112 | flex-direction: column;
113 | justify-content: center;
114 | padding: 0 20px;
115 | height: var(--widget-2-menu-height);
116 | }
117 |
118 | .widget-2-card .block h2 {
119 | margin: 0 0 6px;
120 | font-size: 18px;
121 | font-weight: 400;
122 | }
123 |
--------------------------------------------------------------------------------
/src/components/widgets/Widget2/styles.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --widget-2-color-primary: #195adc;
3 | --widget-2-sidebar-width: 130px;
4 | --widget-2-menu-height: 200px;
5 | }
6 |
7 | .page.widget-2-page {
8 | margin: 0;
9 | display: grid;
10 | place-items: center;
11 | background: linear-gradient(-135deg, var(--widget-2-color-primary), #0f3278);
12 | color: #f0f5ff;
13 | }
14 |
15 | .widget-2-card {
16 | display: flex;
17 | padding: 0 20px;
18 | width: 440px;
19 | height: var(--widget-2-menu-height);
20 | border-radius: 10px;
21 | background: #101115;
22 | box-shadow: 0 20px 30px rgba(57, 76, 96, 0.06);
23 | }
24 |
25 | .widget-2-card .buttons {
26 | padding-top: 20px;
27 | width: var(--widget-2-sidebar-width);
28 | }
29 |
30 | .widget-2-card .buttons button {
31 | margin: 0;
32 | font-size: 14px;
33 | width: 100%;
34 | height: 40px;
35 | padding: 0 0 0 12px;
36 | background: transparent;
37 | border-radius: 6px;
38 | border: 0;
39 | display: flex;
40 | gap: 8px;
41 | align-items: center;
42 | font-weight: 400;
43 | font-family: inherit;
44 | cursor: pointer;
45 | color: inherit;
46 | }
47 |
48 | .widget-2-card .buttons button:focus {
49 | outline-color: var(--widget-2-color-primary);
50 | outline-offset: 0;
51 | }
52 |
53 | .widget-2-card .buttons button:hover {
54 | background-color: rgb(255 255 255 / 4%);
55 | }
56 |
57 | .widget-2-card .buttons button span {
58 | font-size: 16px;
59 | }
60 |
61 | .widget-2-card .buttons button.active {
62 | background: var(--widget-2-color-primary);
63 | color: #f9f9f9;
64 | }
65 |
66 | .widget-2-card .wrapper {
67 | position: relative;
68 | overflow: hidden;
69 | flex: 1 1 auto;
70 | }
71 |
72 | .widget-2-card .wrapper::before,
73 | .widget-2-card .wrapper::after {
74 | content: "";
75 | position: absolute;
76 | z-index: 2;
77 | left: 0;
78 | width: 100%;
79 | height: 36px;
80 | }
81 |
82 | .widget-2-card .wrapper::before {
83 | top: 0;
84 | background: linear-gradient(#101115, rgb(24 24 29 / 0%));
85 | }
86 |
87 | .widget-2-card .wrapper::after {
88 | bottom: 0;
89 | background: linear-gradient(rgb(24 24 29 / 0%), #101115);
90 | }
91 |
92 | .widget-2-card .content {
93 | position: absolute;
94 | z-index: 1;
95 | top: 0;
96 | left: 0;
97 | height: calc(var(--widget-2-menu-height) * 3);
98 | transition: 0.6s;
99 | }
100 |
101 | .widget-2-card .content p {
102 | display: flex;
103 | align-items: center;
104 | line-height: 1.6;
105 | font-size: 13px;
106 | margin: 0;
107 | opacity: 0.5;
108 | }
109 |
110 | .widget-2-card .block {
111 | display: flex;
112 | flex-direction: column;
113 | justify-content: center;
114 | padding: 0 20px;
115 | height: var(--widget-2-menu-height);
116 | }
117 |
118 | .widget-2-card .block h2 {
119 | margin: 0 0 6px;
120 | font-size: 18px;
121 | font-weight: 400;
122 | }
123 |
--------------------------------------------------------------------------------
/src/components/widgets/index.js:
--------------------------------------------------------------------------------
1 | export * from "./Widget1/Widget1";
2 | export * from "./Widget2/Widget2";
3 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | background: #000000;
4 | color: #f9f9f9;
5 | overflow: hidden;
6 | font-family: "Euclid Circular A", "Poppins";
7 | }
8 |
9 | * {
10 | box-sizing: border-box;
11 | }
12 |
13 | .page {
14 | width: 100vw;
15 | height: 100vh;
16 | display: grid;
17 | place-items: center;
18 | }
19 |
--------------------------------------------------------------------------------
/src/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import ReactDOM from 'react-dom/client'
3 | import App from './App.jsx'
4 | import './index.css'
5 |
6 | ReactDOM.createRoot(document.getElementById('root')).render(
7 |
8 |
9 | ,
10 | )
11 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | import react from '@vitejs/plugin-react'
3 |
4 | // https://vitejs.dev/config/
5 | export default defineConfig({
6 | plugins: [react()],
7 | })
8 |
--------------------------------------------------------------------------------