Styling of home

This commit is contained in:
Sebastian Seedorf
2022-08-22 17:04:39 +02:00
parent 537a18fb88
commit d964748a66
55 changed files with 1791 additions and 341 deletions

View File

@@ -0,0 +1,13 @@
.root {
padding: 1em;
border: 0;
background-color: var(--md-sys-color-secondary);
border-radius: 4px;
color: var(--md-sys-color-on-secondary);
transition: box-shadow 0.075s linear;
}
.root:hover,
.root:focus-visible {
box-shadow: 2px 2px 5px 1px rgba(0 0 0 / 50%);
}

View File

@@ -0,0 +1,13 @@
import { ButtonHTMLAttributes, FC } from 'react'
import cx from 'classnames'
import styles from './Button.module.css'
type Props = ButtonHTMLAttributes<HTMLButtonElement>
export const Button: FC<Props> = ({ className, children, ...rest }) => {
return (
<button className={cx(styles.root, className)} {...rest}>
{children}
</button>
)
}

View File

@@ -0,0 +1,15 @@
.root {
display: inline-block;
margin-block-start: -0.4em;
padding-inline: 0.5em;
vertical-align: middle;
}
.link {
display: inline;
padding: 0.2em;
border-radius: 4px;
box-shadow: 0 0 0 1px var(--md-sys-color-tertiary);
color: var(--md-sys-color-tertiary);
font-size: var(--md-sys-typescale-body-small-font-size);
}

View File

@@ -0,0 +1,25 @@
import { FC } from 'react'
import { I18n } from '../I18n/I18n'
import { GraphIcon } from '../../icons/GraphIcon'
import Link from 'next/link'
import { useRouter } from 'next/router'
import styles from './ButtonVisualize.module.css'
interface Props {
groupId?: string
large?: true
}
export const ButtonVisualize: FC<Props> = ({ groupId, large }) => {
const { query } = useRouter()
return (
<span className={styles.root}>
<Link href={{ pathname: !groupId ? '/visualize' : `/visualize/${groupId}`, query }}>
<a className={styles.link}>
{large ? <I18n id={'page.home.pref.visualize'} /> : null}
<GraphIcon />
</a>
</Link>
</span>
)
}

View File

@@ -0,0 +1,58 @@
.collapsible {
position: relative;
}
.toggle {
display: none;
}
.label {
position: absolute;
z-index: 100;
inset-block-start: 0;
inset-inline-end: 0;
}
.label::before {
display: block;
width: 1em;
height: 1em;
border: 1px solid var(--md-ref-palette-neutral-variant80);
border-radius: 4px;
content: "-";
font-size: 0.5em;
line-height: 1em;
margin-block-start: 0.5em;
text-align: center;
}
.content {
position: relative;
overflow: hidden;
max-height: 100vh;
transition: max-height 0.25s ease-in;
}
.content::after {
position: absolute;
height: 3em;
background: linear-gradient(to bottom, rgba(0 0 0 / 0%) 0%, var(--color-bg) 100%);
content: "";
inset-block-end: 0;
inset-inline: 0;
pointer-events: none;
transition: height 0.25s ease-in-out;
}
.toggle:checked + .label::before {
content: "+";
}
.toggle:not(:checked) + .label + .content::after {
height: 0;
}
.toggle:checked + .label + .content {
max-height: 5em;
transition: max-height 0.25s ease-out;
}

View File

@@ -0,0 +1,25 @@
import { FC, PropsWithChildren } from 'react'
import styles from './Collapsible.module.css'
import cx from 'classnames'
import typography from '../../../styles/typography.module.css'
interface Props {
id: string
className?: string
}
export const Collapsible: FC<PropsWithChildren<Props>> = ({ id, className, children }) => {
return (
<div className={cx(styles.collapsible, className)}>
<input id={id} className={styles.toggle} type='checkbox' defaultChecked={true} />
{/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
<label
htmlFor={id}
id={id}
className={cx(styles.label, typography.displaySmall)}
defaultChecked={true}
/>
<div className={styles.content}>{children}</div>
</div>
)
}

View File

@@ -0,0 +1,35 @@
import { createElement, FC, HTMLAttributes, PropsWithChildren } from 'react'
import cx from 'classnames'
import typography from '../../styles/typography.module.css'
interface Props extends HTMLAttributes<HTMLSpanElement & HTMLHeadingElement> {
tag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'span'
type: 'pageTitle' | 'section' | 'subsection'
className?: string
}
export const Heading: FC<PropsWithChildren<Props>> = ({
tag,
type,
className,
children,
...rest
}) => {
const TAG: Record<Props['type'], Exclude<Props['tag'], undefined>> = {
pageTitle: 'h1',
section: 'h2',
subsection: 'h3'
}
return createElement(
tag ?? TAG[type],
{
className: cx(className, {
[typography.displayLarge]: type === 'pageTitle',
[typography.headlineMedium]: type === 'section',
[typography.titleLarge]: type === 'subsection'
}),
...rest
},
children
)
}

View File

@@ -0,0 +1,8 @@
.root {
padding: 1em 0.5em;
border: 1px solid var(--color-text, var(--md-sys-color-on-background));
margin: 0 0 1em;
background-color: var(--color-bg, var(--md-sys-color-background));
border-radius: 4px;
font-size: var(--md-sys-typescale-body-small-font-size);
}

View File

@@ -0,0 +1,9 @@
import { FC, InputHTMLAttributes } from 'react'
import styles from './Input.module.css'
import cx from 'classnames'
type Props = InputHTMLAttributes<HTMLInputElement>
export const Input: FC<Props> = ({ className, ...rest }) => {
return <input className={cx(className, styles.root)} {...rest} />
}

View File

@@ -0,0 +1,3 @@
.subtitle {
margin-block-start: -2em;
}

View File

@@ -0,0 +1,23 @@
import { FC, PropsWithChildren } from 'react'
import cx from 'classnames'
import typography from '../../../styles/typography.module.css'
import styles from './Paragraph.module.css'
interface Props {
size: 'large' | 'medium' | 'small' | 'subtitle'
}
export const Paragraph: FC<PropsWithChildren<Props>> = ({ size, children }) => {
return (
<p
className={cx({
[typography.bodyLarge]: size === 'large',
[typography.bodyMedium]: size === 'medium',
[typography.bodySmall]: size === 'small' || size === 'subtitle',
[styles.subtitle]: size === 'subtitle'
})}
>
{children}
</p>
)
}

View File

@@ -0,0 +1,33 @@
.content {
max-width: 80ch;
margin: 0 auto;
padding-block: 2em;
text-align: justify;
--color-bg: var(--md-sys-color-background);
--color-text: var(--md-sys-color-on-background);
}
.primary {
--color-bg: var(--md-sys-color-primary-container);
--color-text: var(--md-sys-color-on-primary-container);
}
.secondary {
--color-bg: var(--md-sys-color-secondary-container);
--color-text: var(--md-sys-color-on-secondary-container);
}
.tertiary {
--color-bg: var(--md-sys-color-tertiary-container);
--color-text: var(--md-sys-color-on-tertiary-container);
}
.primary,
.secondary,
.tertiary {
background-color: var(--color-bg);
box-shadow: 0 0 0 100vmax var(--color-bg);
clip-path: inset(0 -100vmax);
color: var(--color-text);
}

View File

@@ -0,0 +1,26 @@
import { createContext, FC, PropsWithChildren, useContext } from 'react'
import styles from './Section.module.css'
import cx from 'classnames'
type SectionContextType = 'primary' | 'secondary' | 'tertiary' | undefined
interface Props {
color?: SectionContextType
}
const SectionContext = createContext<SectionContextType>(undefined)
export const useSectionColor = () => useContext(SectionContext)
export const Section: FC<PropsWithChildren<Props>> = ({ color, children }) => {
return (
<div
className={cx(styles.content, {
[styles.primary]: color === 'primary',
[styles.secondary]: color === 'secondary',
[styles.tertiary]: color === 'tertiary'
})}
>
<SectionContext.Provider value={color}>{children}</SectionContext.Provider>
</div>
)
}