components uses css modules; other refactoring
This commit is contained in:
1 parent
0cd61e0ed9
commit
d65aba19a0
28 files changed
+137
-94
No files matched your search
@@ -28,7 +28,12 @@ const Index: NextPage<Props> = props => {
|
||||
<title>{props.data.name}</title>
|
||||
<Meta meta={props.meta} />
|
||||
</Head>
|
||||
<File {...props.data} />
|
||||
<File
|
||||
{...props.data}
|
||||
style={{
|
||||
marginTop: 'var(--size-l)',
|
||||
}}
|
||||
/>
|
||||
<Share />
|
||||
</App>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import cx from 'classnames'
|
||||
import { createElement } from 'react'
|
||||
@@ -10,7 +10,13 @@ export type BlockProps = {
|
||||
}
|
||||
|
||||
export const Block: React.FC<BlockProps> = ({ as = 'div', style, direction, ...props }) => {
|
||||
const newProps = { className: cx('block', direction), style }
|
||||
const directionClass = direction === 'horizontal'
|
||||
? s.horizontal
|
||||
: s.vertical
|
||||
const newProps = {
|
||||
className: cx(s.block, directionClass),
|
||||
style,
|
||||
}
|
||||
|
||||
return createElement(as, newProps, props.children)
|
||||
}
|
||||
@@ -5,10 +5,10 @@
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.block.horizontal {
|
||||
.horizontal {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.block.vertical {
|
||||
.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import { IBreadcumbsPart } from 'src/types'
|
||||
import { Button } from '../Button'
|
||||
@@ -14,7 +14,7 @@ export const Breadcrumbs: React.FC<BreadcrumbsProps> = props => {
|
||||
const items = insertBetween(props.items, () => '/')
|
||||
|
||||
return (
|
||||
<nav className={'breadcrumbs'} style={props.style}>
|
||||
<nav className={s.breadcrumbs} style={props.style}>
|
||||
{items.map((x, i) => {
|
||||
if (typeof x === 'string') {
|
||||
return (
|
||||
|
||||
@@ -11,9 +11,3 @@
|
||||
.breadcrumbs li {
|
||||
margin-bottom: var(--size-xs);
|
||||
}
|
||||
|
||||
.breadcrumbCurrent {
|
||||
color: var(--color-text-second);
|
||||
font-size: var(--font-size-second);
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
@@ -1,9 +1,20 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import Link from 'next/link'
|
||||
import cx from 'classnames'
|
||||
import { useCallback } from 'react'
|
||||
|
||||
const sizeClass = {
|
||||
default: s.sizeDefault,
|
||||
small: s.sizeSmall,
|
||||
}
|
||||
|
||||
const themeClass = {
|
||||
default: '',
|
||||
icon: s.themeIcon,
|
||||
ghost: s.themeGhost,
|
||||
}
|
||||
|
||||
export type ButtonProps = {
|
||||
value?: any
|
||||
style?: React.CSSProperties
|
||||
@@ -15,8 +26,8 @@ export type ButtonProps = {
|
||||
}
|
||||
|
||||
export const Button: React.FC<ButtonProps> = ({ size = 'default', theme = 'default', disabled = false, ...props }) => {
|
||||
const className = cx('button', `size_${size}`, `theme_${theme}`, {
|
||||
disabled
|
||||
const className = cx(s.button, sizeClass[size], themeClass[theme], {
|
||||
[s.disabled]: disabled,
|
||||
})
|
||||
const onClick = useCallback(event => {
|
||||
if (props.onClick) {
|
||||
|
||||
@@ -27,28 +27,28 @@
|
||||
|
||||
/* MODIFICATORS */
|
||||
|
||||
.button.disabled {
|
||||
.disabled {
|
||||
pointer-events: none;
|
||||
color: var(--color-text-second);
|
||||
}
|
||||
|
||||
/* SIZE */
|
||||
|
||||
.button.size_default {
|
||||
.sizeDefault {
|
||||
padding: var(--size-s) var(--size-m);
|
||||
}
|
||||
|
||||
.button.size_small {
|
||||
.sizeSmall {
|
||||
padding: var(--size-xs) var(--size-s);
|
||||
font-size: var(--font-size-second);
|
||||
}
|
||||
|
||||
/* THEME */
|
||||
|
||||
.button.theme_ghost {
|
||||
.themeGhost {
|
||||
border-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.button.theme_icon {
|
||||
.themeIcon {
|
||||
padding: var(--size-xs) var(--size-xs);
|
||||
}
|
||||
@@ -1,8 +1,14 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import cx from 'classnames'
|
||||
import Link from 'next/link'
|
||||
import { Image } from '../Image'
|
||||
|
||||
const layoutClass = {
|
||||
simple: s.simple,
|
||||
featured: s.featured,
|
||||
}
|
||||
|
||||
export type CardLayout = 'simple' | 'featured'
|
||||
export type CardProps = {
|
||||
style?: React.CSSProperties
|
||||
@@ -16,10 +22,10 @@ export type CardProps = {
|
||||
}
|
||||
|
||||
export const Card: React.FC<CardProps> = props => (
|
||||
<div className={cx('card', props.layout)} style={props.style}>
|
||||
<div className={cx(s.card, layoutClass[props.layout])} style={props.style}>
|
||||
<Link href={props.href}>
|
||||
<a>
|
||||
<div className={'card-image'}>
|
||||
<div className={s.image}>
|
||||
<Image
|
||||
alt={props.img.alt}
|
||||
src={props.img.src}
|
||||
@@ -27,7 +33,7 @@ export const Card: React.FC<CardProps> = props => (
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={'card-body'}>
|
||||
<div className={s.body}>
|
||||
{props.children}
|
||||
</div>
|
||||
</a>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* CARD */
|
||||
|
||||
.card {
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow);
|
||||
@@ -23,13 +25,13 @@
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-image {
|
||||
.image {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.card-image img {
|
||||
.image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
@@ -41,19 +43,19 @@
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
.body {
|
||||
background-color: var(--color-back);
|
||||
padding: var(--size-m);
|
||||
}
|
||||
|
||||
/* SIMPLE */
|
||||
|
||||
.card.simple .card-body {
|
||||
.simple .body {
|
||||
position: relative;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.card.simple .card-body:before {
|
||||
.simple .body:before {
|
||||
position: absolute;
|
||||
content: '';
|
||||
background-color: var(--color-back);
|
||||
@@ -65,14 +67,14 @@
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.card.simple > a {
|
||||
.simple > a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* FEATURED */
|
||||
|
||||
.card.featured .card-body {
|
||||
.featured .body {
|
||||
position: absolute;
|
||||
|
||||
--offset: var(--size-m);
|
||||
@@ -1,4 +1,4 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
export type CardGridProps = {
|
||||
style?: React.CSSProperties
|
||||
@@ -6,7 +6,7 @@ export type CardGridProps = {
|
||||
|
||||
export const CardGrid: React.FC<CardGridProps> = props => {
|
||||
return (
|
||||
<section className={'card-grid'} style={props.style}>
|
||||
<section className={s.grid} style={props.style}>
|
||||
{props.children}
|
||||
</section>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.card-grid {
|
||||
.grid {
|
||||
--min-cell-size: 240px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(var(--min-cell-size), 1fr));
|
||||
@@ -8,7 +8,7 @@
|
||||
}
|
||||
|
||||
@media screen and (max-width: 31.25em) {
|
||||
.card-grid {
|
||||
.grid {
|
||||
grid-template-columns: 1fr;
|
||||
/* grid-template-columns: auto; */
|
||||
grid-gap: var(--size-l) 0;
|
||||
@@ -1,27 +1,27 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import { FileDefinition } from 'src/types'
|
||||
import { ext, size } from 'src/lib/file'
|
||||
import { titleCase } from 'src/lib/string'
|
||||
|
||||
export const File: React.SFC<FileDefinition> = props => (
|
||||
<div className={'file'}>
|
||||
<h1>{titleCase(props.name)}</h1>
|
||||
export type FileProps = FileDefinition & {
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
export const File: React.SFC<FileProps> = props => (
|
||||
<div className={s.file} style={props.style}>
|
||||
{!props.cover?.src ? null : (
|
||||
<div className={'file__image'}>
|
||||
<div className={s.image}>
|
||||
<a href={props.file.src} target="_blank" className="invisible">
|
||||
<img src={props.cover.src} alt={props.name} />
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className={'file__file'}>
|
||||
<span>{titleCase(props.name)}</span>
|
||||
</div>
|
||||
|
||||
<div className={'file__file-info'}>
|
||||
<a href={props.file.src} target="_blank">{ext(props.file.name)} ({size(props.file.size)})</a>
|
||||
<div className={s.info}>
|
||||
<span>{props.name}</span>
|
||||
<a href={props.file.src} target="_blank">
|
||||
{ext(props.file.type)} ({size(props.file.size)})
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
@@ -6,20 +6,24 @@
|
||||
margin-bottom: var(--size-xl);
|
||||
}
|
||||
|
||||
.file__image {
|
||||
.image {
|
||||
margin-bottom: var(--size-m);
|
||||
}
|
||||
|
||||
.file__image img {
|
||||
.image img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
box-shadow: var(--shadow);
|
||||
}
|
||||
|
||||
.file__image--big {
|
||||
max-width: 20em;
|
||||
}
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.file__file-info {
|
||||
font-size: var(--font-size-second);
|
||||
}
|
||||
|
||||
.info span {
|
||||
padding-bottom: var(--size-m);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import { memo, useRef, useEffect, useCallback } from 'react'
|
||||
|
||||
export type ImageProps = {
|
||||
@@ -25,7 +26,7 @@ export const Image: React.FC<ImageProps> = memo(props => {
|
||||
<img
|
||||
ref={ref}
|
||||
onLoad={onLoad}
|
||||
className={'image'}
|
||||
className={s.image}
|
||||
style={props.style}
|
||||
alt={props.alt}
|
||||
src={props.src}
|
||||
|
||||
File renamed without changes.
@@ -1,3 +1,4 @@
|
||||
import s from './styles.module.css'
|
||||
import cx from 'classnames'
|
||||
import { useRouter } from 'next/router'
|
||||
import { ActiveLink } from './ActiveLink'
|
||||
@@ -5,7 +6,6 @@ import { isPartOfPath } from 'src/lib/url'
|
||||
|
||||
export type MenuItemProps = {
|
||||
href: string
|
||||
layout: 'desktop' | 'mobile'
|
||||
}
|
||||
|
||||
export const MenuItem: React.FC<MenuItemProps> = props => {
|
||||
@@ -17,8 +17,8 @@ export const MenuItem: React.FC<MenuItemProps> = props => {
|
||||
|
||||
return (
|
||||
<li
|
||||
className={cx('menuItem', props.layout, {
|
||||
selected,
|
||||
className={cx({
|
||||
[s.selected]: selected,
|
||||
})}
|
||||
>
|
||||
<ActiveLink
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import cx from 'classnames'
|
||||
import { MenuItem } from './MenuItem'
|
||||
import { IMenu } from 'src/types'
|
||||
|
||||
const layoutClass = {
|
||||
desktop: s.desktop,
|
||||
mobile: s.mobile,
|
||||
}
|
||||
|
||||
export type MenuProps = {
|
||||
layout: 'desktop' | 'mobile'
|
||||
items: IMenu[]
|
||||
}
|
||||
|
||||
export const Menu: React.FC<MenuProps> = props => (
|
||||
<menu className={cx('menu', props.layout)}>
|
||||
<menu className={cx(s.menu, layoutClass[props.layout])}>
|
||||
{props.items.map((item, index) => (
|
||||
<MenuItem key={index}
|
||||
href={item.href}
|
||||
layout={props.layout}
|
||||
>
|
||||
{item.name}
|
||||
</MenuItem>
|
||||
|
||||
@@ -7,42 +7,42 @@
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.menu.desktop {
|
||||
/* MENU LAYOUT */
|
||||
|
||||
.desktop {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.menu.mobile {
|
||||
.mobile {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.menuItem {
|
||||
/* MENU ITEM */
|
||||
|
||||
.menu li {
|
||||
position: relative;
|
||||
border-top: var(--menu-mark-thickness) solid rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* MOBILE */
|
||||
/* MENU ITEM MOBILE */
|
||||
|
||||
.menuItem.mobile {
|
||||
.mobile li {
|
||||
font-size: var(--font-size-default);
|
||||
|
||||
padding: var(--size-xs) var(--size-s);
|
||||
}
|
||||
|
||||
.menuItem.mobile.selected {
|
||||
.mobile li.selected {
|
||||
background-color: var(--color-back-opposite);
|
||||
color: var(--color-text-opposite)
|
||||
}
|
||||
|
||||
.menuItem.mobile.selected a {
|
||||
color: var(--color-text-opposite)
|
||||
}
|
||||
/* MENU ITEM DESKTOP */
|
||||
|
||||
/* DESKTOP */
|
||||
|
||||
.menuItem.desktop {
|
||||
.desktop li {
|
||||
padding: var(--size-xs) var(--size-s);
|
||||
}
|
||||
|
||||
.menuItem.desktop.selected {
|
||||
.desktop li.selected {
|
||||
border-top-color: var(--color-back-opposite);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import cx from 'classnames'
|
||||
import { Button } from '../Button'
|
||||
@@ -17,9 +17,9 @@ export const MenuToggle: React.FC<IMenuToggleProps> = props => {
|
||||
theme={'icon'}
|
||||
>
|
||||
<div
|
||||
className={cx('toggle', {
|
||||
open: props.open,
|
||||
close: !props.open,
|
||||
className={cx(s.toggle, {
|
||||
[s.open]: props.open,
|
||||
[s.close]: !props.open,
|
||||
})}
|
||||
/>
|
||||
</Button>
|
||||
|
||||
File renamed without changes.
@@ -1,4 +1,4 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import { Transition } from './Transition'
|
||||
import { useReducedMotion } from '../../hooks/useReducedMotion'
|
||||
@@ -34,7 +34,7 @@ export const Overlay: React.FC<IOverlayProps> = props => {
|
||||
>
|
||||
<div
|
||||
onClick={onClick}
|
||||
className={'overlay'}
|
||||
className={s.overlay}
|
||||
style={props.style}
|
||||
>
|
||||
{props.children}
|
||||
|
||||
File renamed without changes.
@@ -1,7 +1,6 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import { Share } from '../Share'
|
||||
import { Html } from '../Html'
|
||||
import { PageMeta } from '../PageMeta'
|
||||
import { ITag } from 'src/types'
|
||||
|
||||
@@ -12,7 +11,7 @@ export type PageProps = {
|
||||
}
|
||||
|
||||
export const Page: React.FC<PageProps> = props => (
|
||||
<div className={'page'} style={props.style}>
|
||||
<div className={s.page} style={props.style}>
|
||||
{props.children}
|
||||
<hr />
|
||||
<Share />
|
||||
|
||||
File renamed without changes.
@@ -1,4 +1,4 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import cx from 'classnames'
|
||||
import { dateFormat } from 'src/lib/date'
|
||||
@@ -18,7 +18,9 @@ export const PageMeta: React.FC<PageMetaProps> = props => {
|
||||
const direction: Direction = mobile ? 'vertical' : 'horizontal'
|
||||
|
||||
return (
|
||||
<div className={cx('pageMeta', center)} style={props.style}>
|
||||
<div className={cx(s.pageMeta, {
|
||||
[s.center]: center,
|
||||
})} style={props.style}>
|
||||
{!props.date ? null : (
|
||||
<p className={'date'}>Опубликовано {dateFormat(props.date)}</p>
|
||||
)}
|
||||
|
||||
File renamed without changes.
@@ -1,9 +1,14 @@
|
||||
import './styles.css'
|
||||
import s from './styles.module.css'
|
||||
|
||||
import cx from 'classnames'
|
||||
import { ITag } from 'src/types'
|
||||
import { Button } from '../Button'
|
||||
|
||||
const directionClass = {
|
||||
horizontal: '',
|
||||
vertical: s.vertical,
|
||||
}
|
||||
|
||||
export type Direction = 'horizontal' | 'vertical'
|
||||
|
||||
export type TagProps = {
|
||||
@@ -12,7 +17,7 @@ export type TagProps = {
|
||||
}
|
||||
|
||||
export const Tag: React.FC<TagProps> = props => (
|
||||
<li className={cx('tagsItem', props.direction)}>
|
||||
<li>
|
||||
<Button
|
||||
href={props.href}
|
||||
size={'small'}
|
||||
@@ -29,7 +34,7 @@ export type TagListProps = {
|
||||
}
|
||||
|
||||
export const TagList: React.FC<TagListProps> = props => (
|
||||
<ul className={cx('tags', props.direction)}>
|
||||
<ul className={cx(s.tags, directionClass[props.direction])}>
|
||||
{props.items.map(x => (
|
||||
<Tag
|
||||
key={x.slug}
|
||||
|
||||
@@ -8,23 +8,27 @@
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.tags.vertical {
|
||||
/* LAYOUT */
|
||||
|
||||
.vertical {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.tagsItem {
|
||||
/* ITEM */
|
||||
|
||||
.tags li {
|
||||
margin-right: var(--size-s);
|
||||
margin-bottom: var(--size-s);
|
||||
}
|
||||
|
||||
.tagsItem:last-child {
|
||||
.tags li:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.tagsItem.vertical {
|
||||
.tags.vertical li {
|
||||
margin-bottom: var(--size-s);
|
||||
}
|
||||
|
||||
.tagsItem.tags.vertical:last-child {
|
||||
.tags.vertical li:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
Reference in new issue
Block a user