Created Layout & Responsive Header Component
This commit is contained in:
14
README.md
14
README.md
@@ -6,20 +6,22 @@ Built using Next.js and Tailwind CSS.
|
||||
|
||||
1. Clone the repository:
|
||||
|
||||
```
|
||||
```bash
|
||||
git clone https://github.com/aftabrehan/zin-tools.git
|
||||
# or
|
||||
gh repo clone aftabrehan/zin-tools
|
||||
```
|
||||
|
||||
2. Install the required dependencies:
|
||||
|
||||
```bash
|
||||
npm
|
||||
npm install
|
||||
# or
|
||||
yarn
|
||||
yarn install
|
||||
# or
|
||||
pnpm
|
||||
pnpm install
|
||||
# or
|
||||
bun
|
||||
bun install
|
||||
```
|
||||
|
||||
3. Run the development server:
|
||||
@@ -36,7 +38,5 @@ bun dev
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
|
||||
|
||||
> [!NOTE]
|
||||
> This project is created solely for test/portfolio purposes, and you are free to use it as you see fit.
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { Inter } from 'next/font/google'
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
import { Header } from '@/components/header'
|
||||
import { Footer } from '@/components/footer'
|
||||
|
||||
import './globals.css'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
@@ -16,7 +20,17 @@ export default function RootLayout({
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
<body className={inter.className}>
|
||||
<Header />
|
||||
<main className="w-full min-h-[calc(100vh-144px)] mt-36">
|
||||
<div className="w-full max-w-7xl mx-auto h-full">{children}</div>
|
||||
</main>
|
||||
<div
|
||||
id="modal"
|
||||
className="flex items-center justify-center w-screen h-screen fixed top-0 left-[50%] translate-x-[-50%] z-1000 overflow-y-hidden pointer-events-none"
|
||||
/>
|
||||
<Footer />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const NotFoundPage = () => (
|
||||
<main className="w-full h-full">
|
||||
<p>Not Found Page</p>
|
||||
</main>
|
||||
<div className="w-full h-full">
|
||||
<p>404 Page</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default NotFoundPage
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
const Home = () => (
|
||||
<main className="w-full h-full">
|
||||
<p>My Clean App</p>
|
||||
</main>
|
||||
<div className="w-full h-full">
|
||||
<p>Home Page</p>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default Home
|
||||
|
||||
42
components/MobileNav.tsx
Normal file
42
components/MobileNav.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
'use client'
|
||||
|
||||
import { useState } from 'react'
|
||||
import Image from 'next/image'
|
||||
|
||||
import { Modal } from '@/components//modal/modal'
|
||||
import { NavDropdown } from '@/components/nav-dropdown'
|
||||
|
||||
import { ALL_NAV_ITEMS } from '@/constants/nav-items'
|
||||
|
||||
export const MobileNav = () => {
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
<button
|
||||
className="w-12 h-12 flex items-center justify-center rounded-md"
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
style={{ background: isOpen ? '#000' : '#f4f4f5' }}
|
||||
>
|
||||
<Image
|
||||
alt=""
|
||||
src={isOpen ? '/cross.svg' : '/hamburger.svg'}
|
||||
width={24}
|
||||
height={24}
|
||||
/>
|
||||
</button>
|
||||
|
||||
<Modal isOpen={isOpen} close={() => setIsOpen(false)}>
|
||||
<div className="w-full h-[calc(100vh-144px)] mt-36 flex sm:hidden bg-white pointer-events-auto border-t border-zinc-100 border animation-slide-from-right">
|
||||
<nav className="w-full">
|
||||
<ul className="w-full flex flex-col items-end justify-center gap-2 p-4">
|
||||
{ALL_NAV_ITEMS.map((navItem, i) => (
|
||||
<NavDropdown key={i} {...navItem} />
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
30
components/button.tsx
Normal file
30
components/button.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
import clsx from 'clsx'
|
||||
|
||||
interface buttonProps {
|
||||
label: string
|
||||
onClick?: () => void
|
||||
variant?: 'primary' | 'secondary'
|
||||
}
|
||||
|
||||
export const Button = ({
|
||||
label,
|
||||
onClick,
|
||||
variant = 'primary',
|
||||
}: buttonProps) => {
|
||||
const cls = {
|
||||
primary: 'bg-primary text-white',
|
||||
secondary: 'text-black hover:bg-zinc-100',
|
||||
}[variant]
|
||||
|
||||
return (
|
||||
<button
|
||||
onClick={onClick}
|
||||
className={clsx(
|
||||
'h-12 px-5 flex items-center justify-center text-base font-medium text-nowrap rounded-full hover:opacity-75 transition-all duration-200',
|
||||
cls
|
||||
)}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
6
components/footer.tsx
Normal file
6
components/footer.tsx
Normal file
@@ -0,0 +1,6 @@
|
||||
export const Footer = () => (
|
||||
// TODO: remove dummy height min-h-[600px]
|
||||
<footer className="w-full min-h-[600px] bg-gray-100">
|
||||
<div className="w-full max-w-7xl mx-auto">Footer</div>
|
||||
</footer>
|
||||
)
|
||||
39
components/header.tsx
Normal file
39
components/header.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import Link from 'next/link'
|
||||
import Image from 'next/image'
|
||||
|
||||
import { Searchbar } from '@/components/search-bar'
|
||||
import { Button } from '@/components/button'
|
||||
import { Navbar } from '@/components/navbar'
|
||||
import { MobileNav } from '@/components/MobileNav'
|
||||
|
||||
export const Header = () => (
|
||||
<header className="w-full h-36 fixed top-0 shadow-header px-4 pt-6 bg-white">
|
||||
<div className="w-full max-w-7xl mx-auto flex flex-col items-center justify-center gap-3 sm:gap-4 md:gap-6">
|
||||
<div className="w-full flex items-center justify-between">
|
||||
<Link href="/" className="overflow-hidden">
|
||||
<Image
|
||||
src="/logo.svg"
|
||||
alt="ZinTools Logo"
|
||||
width={138}
|
||||
height={38}
|
||||
className="w-[120px] sm:w-[130px] md:w-[138px] h-auto"
|
||||
/>
|
||||
</Link>
|
||||
|
||||
<Searchbar className="hidden sm:flex" />
|
||||
|
||||
<div className="flex items-center justify-center gap-2">
|
||||
<Button label="Login" variant="secondary" />
|
||||
<Button label="Sign up" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Navbar className="hidden sm:block" />
|
||||
|
||||
<div className="w-full flex sm:hidden gap-x-2">
|
||||
<Searchbar />
|
||||
<MobileNav />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
19
components/modal/modal-portal.tsx
Normal file
19
components/modal/modal-portal.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import { useRef, useEffect, useState } from 'react'
|
||||
import { createPortal } from 'react-dom'
|
||||
|
||||
interface modalPortal {
|
||||
children: React.ReactNode
|
||||
selector?: string
|
||||
}
|
||||
|
||||
export const ModalPortal = ({ children, selector = 'modal' }: modalPortal) => {
|
||||
const ref = useRef<HTMLDivElement | null>(null)
|
||||
const [mounted, setMounted] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
ref.current = document.querySelector(selector)
|
||||
setMounted(true)
|
||||
}, [selector])
|
||||
|
||||
return mounted && ref.current ? createPortal(children, ref.current) : null
|
||||
}
|
||||
41
components/modal/modal.tsx
Normal file
41
components/modal/modal.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import { useEffect, useRef } from 'react'
|
||||
import clsx from 'clsx'
|
||||
|
||||
import { ModalPortal } from '@/components/modal/modal-portal'
|
||||
|
||||
import { useClickOutside } from '@/hooks/useClickOutside'
|
||||
|
||||
interface modalProps {
|
||||
isOpen: boolean
|
||||
close: () => void
|
||||
children: React.ReactNode
|
||||
closeOnClickAway?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const Modal = ({
|
||||
isOpen,
|
||||
close,
|
||||
children,
|
||||
closeOnClickAway = false,
|
||||
className,
|
||||
}: modalProps) => {
|
||||
const contentRef = useRef(null)
|
||||
|
||||
useClickOutside({
|
||||
onClick: () => closeOnClickAway && close(),
|
||||
ref: contentRef,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) return
|
||||
}, [isOpen])
|
||||
|
||||
return isOpen ? (
|
||||
<ModalPortal selector="#modal">
|
||||
<div ref={contentRef} className={clsx('w-full h-full', className)}>
|
||||
{children}
|
||||
</div>
|
||||
</ModalPortal>
|
||||
) : null
|
||||
}
|
||||
50
components/nav-dropdown.tsx
Normal file
50
components/nav-dropdown.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
import Link from 'next/link'
|
||||
import clsx from 'clsx'
|
||||
|
||||
interface navDropdownProps {
|
||||
title: string
|
||||
link: string
|
||||
options: Array<{ label: string; link: string }>
|
||||
position?: 'left' | 'right' | 'center'
|
||||
}
|
||||
|
||||
export const NavDropdown = ({
|
||||
title,
|
||||
link,
|
||||
options,
|
||||
position = 'center',
|
||||
}: navDropdownProps) => {
|
||||
const positionCls = {
|
||||
left: 'left-0',
|
||||
right: 'right-0',
|
||||
center: '',
|
||||
}[position]
|
||||
|
||||
return (
|
||||
<li className="group relative flex items-center justify-center">
|
||||
<Link
|
||||
href={link}
|
||||
className="relative text-base sm:text-sm font-medium whitespace-nowrap px-3 py-3.5 after:absolute after:bottom-0 after:left-0 after:content-none::after after:w-full after:h-[2px] after:bg-primary after:hidden group-hover:after:block"
|
||||
>
|
||||
{title}
|
||||
</Link>
|
||||
|
||||
<div
|
||||
className={clsx(
|
||||
'hidden sm:group-hover:flex absolute top-12 flex-col min-w-[220px] gap-2 p-4 bg-white rounded-b-md shadow-md border border-zinc-1',
|
||||
positionCls
|
||||
)}
|
||||
>
|
||||
{options.map(({ label, link: opLink }, i) => (
|
||||
<Link
|
||||
key={i}
|
||||
href={opLink}
|
||||
className="w-full p-2 hover:bg-zinc-100 rounded-md transition-colors duration-200 text-sm"
|
||||
>
|
||||
{label}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
45
components/navbar.tsx
Normal file
45
components/navbar.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
import clsx from 'clsx'
|
||||
|
||||
import { NavDropdown } from '@/components/nav-dropdown'
|
||||
|
||||
import { ALL_NAV_ITEMS, LESS_NAV_ITEMS } from '@/constants/nav-items'
|
||||
|
||||
interface navbarProps {
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const Navbar = ({ className }: navbarProps) => (
|
||||
<nav className={clsx('w-full max-w-6xl', className)}>
|
||||
<ul className="w-full hidden lg:flex items-center justify-between gap-1">
|
||||
{ALL_NAV_ITEMS.map((navItem, i) => (
|
||||
<NavDropdown
|
||||
key={i}
|
||||
position={
|
||||
i === 0
|
||||
? 'left'
|
||||
: i === ALL_NAV_ITEMS.length - 1
|
||||
? 'right'
|
||||
: 'center'
|
||||
}
|
||||
{...navItem}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<ul className="w-full flex lg:hidden items-center justify-between gap-1">
|
||||
{LESS_NAV_ITEMS.map((navItem, i) => (
|
||||
<NavDropdown
|
||||
key={i}
|
||||
position={
|
||||
i === 0
|
||||
? 'left'
|
||||
: i === LESS_NAV_ITEMS.length - 1
|
||||
? 'right'
|
||||
: 'center'
|
||||
}
|
||||
{...navItem}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
33
components/search-bar.tsx
Normal file
33
components/search-bar.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import Image from 'next/image'
|
||||
import clsx from 'clsx'
|
||||
|
||||
interface searchbarProps {
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const Searchbar = ({ className }: searchbarProps) => (
|
||||
<div
|
||||
className={clsx(
|
||||
'flex-1 sm:max-w-[280px] md:max-w-[400px] lg:max-w-[500px] flex items-center justify-between gap-x-4 md:gap-x-6 px-4 sm:px-6 py-1.5 bg-zinc-100 rounded-3xl',
|
||||
className
|
||||
)}
|
||||
>
|
||||
<input
|
||||
type="search"
|
||||
placeholder="Search for Movies, TV Shows, Themes & Cast"
|
||||
className="flex flex-1 outline-none bg-transparent text-black text-base"
|
||||
/>
|
||||
<div className="flex items-center justify-end gap-x-2 md:gap-x-6">
|
||||
<div className="w-[1px] h-9 bg-gray-400/50 cursor-default" />
|
||||
<div className="w-8 h-8 flex items-center justify-center hover:bg-gray-200 rounded-full cursor-pointer">
|
||||
<Image
|
||||
alt=""
|
||||
src="/search.svg"
|
||||
width={16}
|
||||
height={16}
|
||||
className="select-none"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
28
constants/nav-items.ts
Normal file
28
constants/nav-items.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
const placeholderOptions = [
|
||||
{ label: 'Stock Fotage', link: '/' },
|
||||
{ label: 'Motion Graphics', link: '/' },
|
||||
{ label: 'All Stock Videos', link: '/' },
|
||||
]
|
||||
|
||||
const commonProps = { link: '/', options: placeholderOptions }
|
||||
|
||||
export const ALL_NAV_ITEMS = [
|
||||
{ title: 'Stock Video', ...commonProps },
|
||||
{ title: 'Video Templates', ...commonProps },
|
||||
{ title: 'Music', ...commonProps },
|
||||
{ title: 'Sound Effects', ...commonProps },
|
||||
{ title: 'Graphic Templates', ...commonProps },
|
||||
{ title: 'Presentation Templates', ...commonProps },
|
||||
{ title: 'Graphics', ...commonProps },
|
||||
{ title: 'Photos', ...commonProps },
|
||||
{ title: 'More', ...commonProps },
|
||||
]
|
||||
|
||||
export const LESS_NAV_ITEMS = [
|
||||
{ title: 'Stock Video', ...commonProps },
|
||||
{ title: 'Video Templates', ...commonProps },
|
||||
{ title: 'Music', ...commonProps },
|
||||
{ title: 'Sound Effects', ...commonProps },
|
||||
{ title: 'Graphic Templates', ...commonProps },
|
||||
{ title: 'More', ...commonProps },
|
||||
]
|
||||
16
hooks/useClickOutside.ts
Normal file
16
hooks/useClickOutside.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { useEffect } from 'react'
|
||||
|
||||
interface funcProps {
|
||||
onClick: () => void
|
||||
ref: { current: HTMLDivElement } | { current: null }
|
||||
}
|
||||
|
||||
export const useClickOutside = ({ onClick, ref }: funcProps) => {
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (e: any) =>
|
||||
ref.current && !ref.current.contains(e.target) && onClick()
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside)
|
||||
return () => document.removeEventListener('mousedown', handleClickOutside)
|
||||
}, [onClick, ref])
|
||||
}
|
||||
11
package.json
11
package.json
@@ -9,19 +9,20 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.0",
|
||||
"next": "14.1.0",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"next": "14.1.0"
|
||||
"react-dom": "^18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^18",
|
||||
"@types/react-dom": "^18",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.1.0",
|
||||
"postcss": "^8",
|
||||
"tailwindcss": "^3.3.0",
|
||||
"eslint": "^8",
|
||||
"eslint-config-next": "14.1.0"
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
|
||||
3
public/cross.svg
Normal file
3
public/cross.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M4.30563 18.2187C3.89812 18.6263 3.89812 19.2869 4.30563 19.6944C4.71313 20.1019 5.37383 20.1019 5.78133 19.6944L4.30563 18.2187ZM12.7378 12.7378C13.1453 12.3303 13.1453 11.6697 12.7378 11.2622C12.3303 10.8547 11.6697 10.8547 11.2622 11.2622L12.7378 12.7378ZM11.2622 11.2622C10.8547 11.6697 10.8547 12.3303 11.2622 12.7378C11.6697 13.1453 12.3303 13.1453 12.7378 12.7378L11.2622 11.2622ZM19.6944 5.78133C20.1019 5.37383 20.1019 4.71313 19.6944 4.30563C19.2869 3.89812 18.6263 3.89812 18.2187 4.30563L19.6944 5.78133ZM12.7378 11.2622C12.3303 10.8547 11.6697 10.8547 11.2622 11.2622C10.8547 11.6697 10.8547 12.3303 11.2622 12.7378L12.7378 11.2622ZM18.2187 19.6944C18.6263 20.1019 19.2869 20.1019 19.6944 19.6944C20.1019 19.2869 20.1019 18.6263 19.6944 18.2187L18.2187 19.6944ZM11.2622 12.7378C11.6697 13.1453 12.3303 13.1453 12.7378 12.7378C13.1453 12.3303 13.1453 11.6697 12.7378 11.2622L11.2622 12.7378ZM5.78133 4.30563C5.37383 3.89812 4.71313 3.89812 4.30563 4.30563C3.89812 4.71313 3.89812 5.37383 4.30563 5.78133L5.78133 4.30563ZM5.78133 19.6944L12.7378 12.7378L11.2622 11.2622L4.30563 18.2187L5.78133 19.6944ZM12.7378 12.7378L19.6944 5.78133L18.2187 4.30563L11.2622 11.2622L12.7378 12.7378ZM11.2622 12.7378L18.2187 19.6944L19.6944 18.2187L12.7378 11.2622L11.2622 12.7378ZM12.7378 11.2622L5.78133 4.30563L4.30563 5.78133L11.2622 12.7378L12.7378 11.2622Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
5
public/hamburger.svg
Normal file
5
public/hamburger.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M20 5H4" stroke="black" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M20 12H4" stroke="black" stroke-width="2" stroke-linecap="round"/>
|
||||
<path d="M20 19H4" stroke="black" stroke-width="2" stroke-linecap="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 330 B |
3
public/search.svg
Normal file
3
public/search.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.7834 14.6461L11.3595 10.2222C12.3467 8.94813 12.8117 7.34591 12.6598 5.7413C12.5079 4.13668 11.7506 2.65014 10.5419 1.58393C9.33315 0.517707 7.76372 -0.0481467 6.1527 0.00141407C4.54168 0.0509749 3.01 0.71223 1.8691 1.85073C0.728193 2.98923 0.0637091 4.51951 0.0107508 6.13042C-0.0422074 7.74134 0.520335 9.31196 1.584 10.5229C2.64767 11.7339 4.13261 12.4943 5.7369 12.6496C7.34118 12.8049 8.94439 12.3433 10.2205 11.3588L14.6444 15.7835C14.7968 15.9266 14.9989 16.0048 15.2079 16.0015C15.4169 15.9982 15.6165 15.9137 15.7643 15.7659C15.9121 15.6181 15.9966 15.4186 15.9998 15.2096C16.0031 15.0006 15.9249 14.7985 15.7818 14.6461H15.7834ZM3.01238 9.69351C2.35138 9.03269 1.90119 8.1907 1.71875 7.27402C1.53631 6.35733 1.62981 5.40713 1.98743 4.54359C2.34505 3.68005 2.95072 2.94195 3.72785 2.42266C4.50497 1.90336 5.41864 1.62618 6.35331 1.62618C7.28797 1.62618 8.20164 1.90336 8.97877 2.42266C9.75589 2.94195 10.3616 3.68005 10.7192 4.54359C11.0768 5.40713 11.1703 6.35733 10.9879 7.27402C10.8054 8.1907 10.3552 9.03269 9.69424 9.69351C9.25757 10.1359 8.73738 10.4872 8.16386 10.7269C7.59035 10.9667 6.97492 11.0902 6.35331 11.0902C5.73169 11.0902 5.11627 10.9667 4.54275 10.7269C3.96923 10.4872 3.44905 10.1359 3.01238 9.69351Z" fill="#9DA3AE"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -1,20 +1,21 @@
|
||||
import type { Config } from "tailwindcss";
|
||||
import type { Config } from 'tailwindcss'
|
||||
|
||||
const config: Config = {
|
||||
content: [
|
||||
"./pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||
'./pages/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./components/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
'./app/**/*.{js,ts,jsx,tsx,mdx}',
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
backgroundImage: {
|
||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||
"gradient-conic":
|
||||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
||||
colors: {
|
||||
primary: '#616DF4',
|
||||
},
|
||||
boxShadow: {
|
||||
header: '0px 4px 12px 0px rgba(189, 189, 189, 0.25)',
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
};
|
||||
export default config;
|
||||
}
|
||||
export default config
|
||||
|
||||
@@ -591,6 +591,11 @@ client-only@0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
|
||||
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
|
||||
|
||||
clsx@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb"
|
||||
integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg==
|
||||
|
||||
color-convert@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||
@@ -2242,6 +2247,7 @@ streamsearch@^1.1.0:
|
||||
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
|
||||
|
||||
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
|
||||
name string-width-cjs
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||
@@ -2302,6 +2308,7 @@ string.prototype.trimstart@^1.0.7:
|
||||
es-abstract "^1.22.1"
|
||||
|
||||
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||
name strip-ansi-cjs
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
|
||||
Reference in New Issue
Block a user