add initial contrast theme

This commit is contained in:
tmshv committed 2022-10-12 13:30:39 +06:00
1 parent c4e13e8e1b
commit 3fa99b28de
15 files changed
+157 -9

No files matched your search

+3
View File
@@ -8,6 +8,7 @@ import App from "next/app"
import Head from "next/head"
import { YMetrika } from "src/components/YMetrika"
import { GAnalytics } from "src/components/GAnalytics"
import { Theme } from "@/ui/theme/Theme"
export default class MyApp extends App {
render() {
@@ -41,7 +42,9 @@ export default class MyApp extends App {
<YMetrika account={24027460} />
<GAnalytics account={"UA-60209057-1"} />
</Head>
<Theme>
<Component {...pageProps} />
</Theme>
</>
)
}
+10
View File
@@ -10,6 +10,9 @@ import { useMobile } from "src/hooks/useMobile"
import { Gosuslugi } from "../Gosuslugi"
import { Navigation } from "@/components/Navigation"
import { Box } from "@/ui/Box"
import { Button } from "@/ui/Button"
import { EyeOpenIcon } from "@radix-ui/react-icons"
import { useTheme } from "@/ui/theme/useTheme"
export type AppProps = {
showAuthor?: boolean
@@ -25,6 +28,7 @@ export const App: React.FC<AppProps> = ({ showAuthor = false, menu, ...props })
const blockStyle = {
justifyContent: "center",
}
const { theme, setTheme } = useTheme()
return (
<ConfigContext.Provider value={{
@@ -61,6 +65,12 @@ export const App: React.FC<AppProps> = ({ showAuthor = false, menu, ...props })
}}>
<Gosuslugi />
</div>
<Button theme="icon" size="default" onClick={() => {
setTheme(theme === "default" ? "contrast" : "default")
}}>
<EyeOpenIcon width={24} height={24} />
</Button>
</Footer>
)}
>
+5 -4
View File
@@ -5,6 +5,8 @@
box-shadow: var(--shadow);
overflow: hidden;
transition: box-shadow 150ms;
border: var(--border);
}
.card:hover {
@@ -52,8 +54,8 @@
border-radius: var(--radius) var(--radius) 0 0;
width: 100%;
height: var(--radius);
top: calc(var(--radius) * -1);
height: var(--size-m);
top: calc(var(--size-m) * -1);
left: 0;
}
@@ -68,10 +70,9 @@
position: absolute;
--offset: var(--size-m);
--r: var(--size-s);
left: var(--offset);
right: var(--offset);
bottom: var(--offset);
border-radius: var(--radius) var(--radius) var(--r) var(--r);
border-radius: var(--radius-small);
}
+9
View File
@@ -6,6 +6,7 @@ import { Author } from "./Author"
import { Spacer } from "../Spacer"
import { Contacts } from "../Contacts"
import { Box } from "@/ui/Box"
import { Panel } from "@/ui/Panel"
export type FooterProps = {
showAuthor: boolean
@@ -14,12 +15,20 @@ export type FooterProps = {
export const Footer: React.FC<FooterProps> = ({ showAuthor, children }) => (
<footer className={cx(s.footer, "opposite")}>
<Box>
<Box vertical align={false} style={{
marginBottom: "var(--size-l)",
}}>
<Contacts />
</Box>
<Panel style={{
marginBottom: "var(--size-l)",
}}>
<Contacts />
</Panel>
</Box>
{children}
<Box>
+7 -1
View File
@@ -21,7 +21,7 @@
.menuItem {
user-select: none;
background-color: var(--color-back-main);
border-radius: var(--size-s);
border-radius: var(--radius-small);
transition: box-shadow 200ms ease-in, background-color 200ms ease-in;
padding: var(--size-s) var(--size-s);
}
@@ -32,6 +32,12 @@
.menuItem.active:hover {
box-shadow: var(--shadow);
color: var(--color-hover);
background-color: var(--color-hover-back);
}
.menuItem.active:hover a {
color: var(--color-hover);
}
.menuItem.current {
+2
View File
@@ -7,6 +7,8 @@ import { ConfigContext } from "src/context/ConfigContext"
import { Box } from "@/ui/Box"
import { Spacer } from "../Spacer"
import { useToggle } from "react-use"
import { Button } from "@/ui/Button"
import { EyeOpenIcon } from "@radix-ui/react-icons"
export type NavigationProps = {
style?: React.CSSProperties
+8 -3
View File
@@ -1,6 +1,7 @@
import s from "./wrapper.module.css"
import cx from "classnames"
import { useTheme } from "@/ui/theme/useTheme"
export type WrapperProps = {
header: React.ReactNode
@@ -10,8 +11,11 @@ export type WrapperProps = {
children?: React.ReactNode
}
export const Wrapper: React.FC<WrapperProps> = props => (
<div className={cx(s.container, "theme-default")} style={props.style}>
export const Wrapper: React.FC<WrapperProps> = props => {
const { theme } = useTheme()
return (
<div className={cx(s.container, `theme-${theme}`)} style={props.style}>
{props.header}
<main className={s.main} style={props.mainStyle}>
@@ -20,4 +24,5 @@ export const Wrapper: React.FC<WrapperProps> = props => (
{props.footer}
</div>
)
)
}
+45
View File
@@ -34,6 +34,7 @@
--color-back-opposite: hsl(0, 0%, 15%);
--color-shadow: rgba(27, 51, 88, 0.25);
--color-hover: none;
/* SIZE */
--size-xs: 0.35rem;
@@ -44,6 +45,7 @@
/* EFFECTS */
--radius: 16px;
--radius-small: 12px;
--shadow:
0 2px 4px rgba(27, 51, 88, 0.2),
0 4px 8px -8px rgba(0, 0, 0, 0.2),
@@ -51,6 +53,7 @@
--shadow-active:
0 12px 24px -8px rgba(27, 51, 88, 0.25),
0 8px 16px -8px rgba(0, 0, 0, 0.3);
--border: none;
/* SPECIAL */
--article-line-height: 1.5em;
@@ -191,3 +194,45 @@ h3 {
--shadow-active: none;
}
}
/* CONTRAST THEME */
.theme-contrast {
/* FONTS */
--title-font: 'Roboto', Helvetica, sans-serif;
--text-font: 'Roboto', Helvetica, sans-serif;
/* TEXT COLOR */
--color-text: black;
--color-text-second: black;
--color-text-opposite: white;
--color-back-main: white;
--color-back: white;
--color-back-active: hsl(240, 10%, 20%);
/* --color-back-opposite: hsl(240, 10%, 80%); */
--color-back-opposite: black;
--color-link: hsl(240, 10%, 40%);
--color-link-opposite: hsl(240, 10%, 60%);
--color-hover: white;
--color-hover-back: black;
/* EFFECTS */
/* --radius: 0px; */
--shadow: none;
--shadow-active: none;
/* FONTS */
--font-size-default: 14pt;
--font-size-accent: 24pt;
--font-size-second: 12pt;
--font-size-h1: 5rem;
--font-size-h2: 3rem;
--font-size-h3: 1.5rem;
/* OTHER */
--radius: 0;
--radius-small: 0;
--border: 5px solid var(--color-back-opposite);
}
+3 -1
View File
@@ -8,6 +8,7 @@ const cx = classnames.bind(s)
export type BoxProps = {
as?: keyof HTMLElementTagNameMap
children?: React.ReactNode
className?: string
style?: React.CSSProperties
wrap?: boolean
align?: boolean
@@ -22,10 +23,11 @@ export const Box: React.FC<BoxProps> = ({
center = false,
align = true,
style,
className,
...props
}) => {
const newProps = {
className: cx(s.box, { vertical, align, center, wrap }),
className: cx(s.box, className, { vertical, align, center, wrap }),
style,
}
+19
View File
@@ -0,0 +1,19 @@
import s from "./panel.module.css"
import { Box } from "../Box"
export type PanelProps = {
children?: React.ReactNode
style?: React.CSSProperties
}
export const Panel: React.FC<PanelProps> = ({
style,
children,
}) => {
return (
<Box vertical align={false} className={`${s.panel} ${s.default}`} style={style}>
{children}
</Box>
)
}
+8
View File
@@ -0,0 +1,8 @@
.panel {
padding: var(--size-m);
border-radius: var(--radius);
}
.default {
background-color: white;
}
+17
View File
@@ -0,0 +1,17 @@
import { useState } from "react"
import { ThemeContext } from "./ThemeContext"
import { ThemeType } from "./types"
export type ThemeProps = {
children?: React.ReactNode
}
export const Theme: React.FC<ThemeProps> = ({ children }) => {
const [theme, setTheme] = useState<ThemeType>("default")
return (
<ThemeContext.Provider value={[theme, setTheme]}>
{children}
</ThemeContext.Provider>
)
}
+4
View File
@@ -0,0 +1,4 @@
import { createContext } from "react"
import { SetTheme, ThemeType } from "./types"
export const ThemeContext = createContext<[ThemeType, SetTheme]>("default")
+2
View File
@@ -0,0 +1,2 @@
export type ThemeType = "default" | "contrast"
export type SetTheme = (theme: ThemeType) => void
+15
View File
@@ -0,0 +1,15 @@
import { useContext } from "react"
import { ThemeContext } from "./ThemeContext"
import { SetTheme, ThemeType } from "./types"
export type UseThemeResult = {
theme: ThemeType
setTheme: SetTheme
// toggleTheme:
}
export function useTheme(): UseThemeResult {
const [theme, setTheme] = useContext(ThemeContext)
return { theme, setTheme }
}