mirror of
https://github.com/StepanovPlaton/torrent_frontend.git
synced 2026-04-03 12:20:48 +04:00
Adaptive header for modile and tablet
This commit is contained in:
9
package-lock.json
generated
9
package-lock.json
generated
@@ -8,6 +8,7 @@
|
|||||||
"name": "torrent_frontend",
|
"name": "torrent_frontend",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"clsx": "^2.1.1",
|
||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
@@ -1088,6 +1089,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
|
||||||
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/clsx": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"clsx": "^2.1.1",
|
||||||
"next": "14.2.3",
|
"next": "14.2.3",
|
||||||
"next-themes": "^0.3.0",
|
"next-themes": "^0.3.0",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
|
|||||||
@@ -41,3 +41,15 @@ body {
|
|||||||
color: var(--color-fg1);
|
color: var(--color-fg1);
|
||||||
background-color: var(--color-bg0);
|
background-color: var(--color-bg0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 1280px) {
|
||||||
|
:root {
|
||||||
|
--app-width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
:root {
|
||||||
|
font-size: calc((100vh / 1080) * 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,6 @@
|
|||||||
|
import { GameCard } from "@/features/gameCard";
|
||||||
import { Section } from "@/widgets/section";
|
import { Section } from "@/widgets/section";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return <div className="w-full max-w-[var(--app-width)] m-auto"></div>;
|
||||||
<div className="w-full max-w-[var(--app-width)] m-auto">
|
|
||||||
<Section name="Игры">a</Section>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
17
src/features/colorSchemeSwitch/colorSchemeSwitch.tsx
Normal file
17
src/features/colorSchemeSwitch/colorSchemeSwitch.tsx
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { SunIcon } from "@/shared/assets/icons";
|
||||||
|
import { useTheme } from "next-themes";
|
||||||
|
|
||||||
|
export const ColorSchemeSwitch = () => {
|
||||||
|
const { theme, setTheme } = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SunIcon
|
||||||
|
className="mr-5 h-8 w-8 cursor-pointer"
|
||||||
|
onClick={() => setTheme(theme == "light" ? "dark" : "light")}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
3
src/features/colorSchemeSwitch/index.ts
Normal file
3
src/features/colorSchemeSwitch/index.ts
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
import { ColorSchemeSwitch } from "./colorSchemeSwitch";
|
||||||
|
|
||||||
|
export { ColorSchemeSwitch as SchemeSwitch };
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
export const GameCard = () => {
|
export const GameCard = () => {
|
||||||
return <></>;
|
return <></>;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
import { SchemeSwitch } from "./schemeSwitch";
|
|
||||||
|
|
||||||
export { SchemeSwitch };
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
"use client";
|
|
||||||
|
|
||||||
import { SunIcon } from "@/shared/assets/icons";
|
|
||||||
import { useTheme } from "next-themes";
|
|
||||||
|
|
||||||
export const SchemeSwitch = () => {
|
|
||||||
const { theme, setTheme } = useTheme();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<SunIcon
|
|
||||||
className="mr-5 h-8 w-8 cursor-pointer"
|
|
||||||
onClick={() => setTheme(theme == "light" ? "dark" : "light")}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,45 +1,62 @@
|
|||||||
import { SchemeSwitch } from "@/features/schemeSwitch";
|
import { SchemeSwitch } from "@/features/colorSchemeSwitch";
|
||||||
import { PersonIcon, SearchIcon } from "@/shared/assets/icons";
|
import { PersonIcon, SearchIcon } from "@/shared/assets/icons";
|
||||||
|
import { MobileMenu } from "./mobileMenu/mobileMenu";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
const sections = [
|
||||||
|
{ title: "Игры", href: "/games" },
|
||||||
|
{ title: "Фильмы", href: "/films" },
|
||||||
|
{ title: "Аудиокниги", href: "/audiobooks" },
|
||||||
|
];
|
||||||
|
|
||||||
export const Header = () => {
|
export const Header = () => {
|
||||||
return (
|
return (
|
||||||
<header className="w-full h-20 flex justify-around bg-bg1">
|
<header className="w-full h-20 bg-bg1">
|
||||||
<div
|
<div
|
||||||
className="w-full h-full max-w-[var(--app-width)]
|
className="w-full h-full max-w-[var(--app-width)] m-auto px-5
|
||||||
flex items-center justify-between"
|
flex items-center justify-between"
|
||||||
>
|
>
|
||||||
<h1 className="text-5xl font-bold">.Torrent</h1>
|
<h1 className="text-4xl font-bold flex items-center">
|
||||||
<div className="text-3xl">
|
<div className="lp:hidden">
|
||||||
{["Игры", "Фильмы", "Аудиокниги"].map((section) => (
|
<MobileMenu sections={sections} />
|
||||||
<a key={section} className="px-2 cursor-pointer hover:underline">
|
</div>
|
||||||
{section}
|
<Link href="/">.Torrent</Link>
|
||||||
</a>
|
</h1>
|
||||||
))}
|
<div className="hidden text-2xl dsk:block">
|
||||||
</div>
|
{sections.map((section) => (
|
||||||
<div className="flex flex-col items-end">
|
<Link
|
||||||
<span className="flex items-center mb-1 ">
|
key={section.title}
|
||||||
<SchemeSwitch />
|
className="px-5 cursor-pointer hover:underline"
|
||||||
<span className="cursor-pointer flex items-center">
|
href={section.href}
|
||||||
<PersonIcon className="mr-1 h-4 w-4" />
|
>
|
||||||
Войти
|
{section.title}
|
||||||
</span>
|
</Link>
|
||||||
</span>
|
))}
|
||||||
<label className="flex flex-col items-start relative w-36">
|
</div>
|
||||||
<input
|
<div className="flex flex-col items-end">
|
||||||
className="peer/search w-full rounded-lg bg-bg4 px-2"
|
<span className="flex items-center mb-1 ">
|
||||||
placeholder=" "
|
<SchemeSwitch />
|
||||||
/>
|
<span className="cursor-pointer flex items-center">
|
||||||
<span
|
<PersonIcon className="mr-1 h-4 w-4" />
|
||||||
className="peer-focus/search:opacity-0
|
Войти
|
||||||
peer-[:not(:placeholder-shown)]/search:opacity-0
|
</span>
|
||||||
transition-all h-0 flex items-center relative bottom-3"
|
</span>
|
||||||
>
|
<label className="flex flex-col items-start relative w-36">
|
||||||
<SearchIcon className="w-4 h-4 mx-2" />
|
<input
|
||||||
Поиск
|
className="peer/search w-full rounded-lg bg-bg4 px-2"
|
||||||
</span>
|
placeholder=" "
|
||||||
</label>
|
/>
|
||||||
</div>
|
<span
|
||||||
</div>
|
className="peer-focus/search:opacity-0
|
||||||
</header>
|
peer-[:not(:placeholder-shown)]/search:opacity-0
|
||||||
);
|
transition-all h-0 flex items-center relative bottom-3"
|
||||||
|
>
|
||||||
|
<SearchIcon className="w-4 h-4 mx-2" />
|
||||||
|
Поиск
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
50
src/widgets/header/mobileMenu/mobileMenu.tsx
Normal file
50
src/widgets/header/mobileMenu/mobileMenu.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import clsx from "clsx";
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export const MobileMenu = ({
|
||||||
|
sections,
|
||||||
|
}: {
|
||||||
|
sections: { title: string; href: string }[];
|
||||||
|
}) => {
|
||||||
|
const [open, changeMenuOpen] = useState<boolean>(false);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
<button
|
||||||
|
className="peer w-16 h-16 *:w-12 *:h-1 *:bg-fg1 *:my-3
|
||||||
|
*:transition-all *:duration-300 *:relative"
|
||||||
|
onClick={() => changeMenuOpen(!open)}
|
||||||
|
onBlur={() => changeMenuOpen(false)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={clsx(open && "rotate-45 top-4", !open && "top-0")}
|
||||||
|
></div>
|
||||||
|
<div className={clsx(open && "opacity-0")}></div>
|
||||||
|
<div
|
||||||
|
className={clsx(open && "-rotate-45 bottom-4", !open && "bottom-0")}
|
||||||
|
></div>
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
className={clsx(
|
||||||
|
"h-0 absolute transition-all duration-300 overflow-hidden\
|
||||||
|
bg-bg4 rounded-lg px-4 flex flex-col",
|
||||||
|
open && "h-32"
|
||||||
|
)}
|
||||||
|
onClick={() => changeMenuOpen(false)}
|
||||||
|
>
|
||||||
|
{sections.map((section) => (
|
||||||
|
<Link
|
||||||
|
key={section.title}
|
||||||
|
className="text-xl py-2 cursor-pointer hover:underline"
|
||||||
|
href={section.href}
|
||||||
|
>
|
||||||
|
{section.title}
|
||||||
|
</Link>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
export const Section = ({
|
export const Section = ({
|
||||||
name,
|
name,
|
||||||
children,
|
children,
|
||||||
}: {
|
}: {
|
||||||
name: string;
|
name: string;
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
// open section onClick
|
// open section onClick
|
||||||
<section className="w-full mt-8 cursor-pointer">
|
<section className="w-full m-5 mt-8 cursor-pointer">
|
||||||
<h2 className="text-4xl">{name}</h2>
|
<h2 className="text-4xl">{name}</h2>
|
||||||
<div>{children}</div>
|
<div>{children}</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,29 +1,34 @@
|
|||||||
import type { Config } from "tailwindcss";
|
import type { Config } from "tailwindcss";
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
content: [
|
content: [
|
||||||
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
"./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
"./src/components/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
"./src/**/*.{js,ts,jsx,tsx,mdx}",
|
"./src/**/*.{js,ts,jsx,tsx,mdx}",
|
||||||
],
|
],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
backgroundImage: {
|
backgroundImage: {
|
||||||
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
"gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
|
||||||
"gradient-conic":
|
"gradient-conic":
|
||||||
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
|
||||||
},
|
},
|
||||||
colors: {
|
colors: {
|
||||||
bg0: "var(--color-bg0)",
|
bg0: "var(--color-bg0)",
|
||||||
bg1: "var(--color-bg1)",
|
bg1: "var(--color-bg1)",
|
||||||
bg4: "var(--color-bg4)",
|
bg4: "var(--color-bg4)",
|
||||||
fg0: "var(--color-fg0)",
|
fg0: "var(--color-fg0)",
|
||||||
fg1: "var(--color-fg1)",
|
fg1: "var(--color-fg1)",
|
||||||
fg4: "var(--color-fg4)",
|
fg4: "var(--color-fg4)",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
screens: {
|
||||||
plugins: [],
|
tb: "640px",
|
||||||
|
lp: "1024px",
|
||||||
|
dsk: "1280px",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [],
|
||||||
};
|
};
|
||||||
export default config;
|
export default config;
|
||||||
|
|||||||
Reference in New Issue
Block a user