mirror of
https://github.com/Aviortheking/next-template.git
synced 2025-06-23 09:39:19 +00:00
Updated to V2
Signed-off-by: Florian Bouillon <florian.bouillon@delta-wings.net>
This commit is contained in:
59
src/client/components/Favicons.tsx
Normal file
59
src/client/components/Favicons.tsx
Normal file
@ -0,0 +1,59 @@
|
||||
import React from 'react'
|
||||
|
||||
export default class Favicons extends React.Component {
|
||||
|
||||
public render = () => (
|
||||
<>
|
||||
<link rel="shortcut icon" href="/favicon.ico"/>
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"/>
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"/>
|
||||
<link rel="icon" type="image/png" sizes="48x48" href="/favicon-48x48.png"/>
|
||||
<link rel="manifest" href="/manifest.json"/>
|
||||
<meta name="mobile-web-app-capable" content="yes"/>
|
||||
<meta name="theme-color" content="#123456"/>
|
||||
<meta name="application-name" content="Next Template"/>
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png"/>
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png"/>
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png"/>
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png"/>
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png"/>
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png"/>
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png"/>
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png"/>
|
||||
<link rel="apple-touch-icon" sizes="167x167" href="/apple-touch-icon-167x167.png"/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png"/>
|
||||
<link rel="apple-touch-icon" sizes="1024x1024" href="/apple-touch-icon-1024x1024.png"/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes"/>
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/>
|
||||
<meta name="apple-mobile-web-app-title" content="Next Template"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/apple-touch-startup-image-640x1136.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/apple-touch-startup-image-750x1334.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/apple-touch-startup-image-828x1792.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/apple-touch-startup-image-1125x2436.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/apple-touch-startup-image-1242x2208.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)" href="/apple-touch-startup-image-1242x2688.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/apple-touch-startup-image-1536x2048.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/apple-touch-startup-image-1668x2224.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/apple-touch-startup-image-1668x2388.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/apple-touch-startup-image-2048x2732.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/apple-touch-startup-image-1620x2160.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/apple-touch-startup-image-1136x640.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/apple-touch-startup-image-1334x750.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/apple-touch-startup-image-1792x828.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/apple-touch-startup-image-2436x1125.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/apple-touch-startup-image-2208x1242.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)" href="/apple-touch-startup-image-2688x1242.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/apple-touch-startup-image-2048x1536.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/apple-touch-startup-image-2224x1668.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/apple-touch-startup-image-2388x1668.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/apple-touch-startup-image-2732x2048.png"/>
|
||||
<link rel="apple-touch-startup-image" media="(device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)" href="/apple-touch-startup-image-2160x1620.png"/>
|
||||
<link rel="icon" type="image/png" sizes="228x228" href="/coast-228x228.png"/>
|
||||
<meta name="msapplication-TileColor" content="#fff"/>
|
||||
<meta name="msapplication-TileImage" content="/mstile-144x144.png"/>
|
||||
<meta name="msapplication-config" content="/browserconfig.xml"/>
|
||||
<link rel="yandex-tableau-widget" href="/yandex-browser-manifest.json"/>
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export default class HelloWorld extends React.Component<Props> {
|
||||
|
||||
public render() {
|
||||
return (
|
||||
<>
|
||||
<h1>{this.props.children}</h1>
|
||||
<style jsx>{`
|
||||
h1
|
||||
font-weight 700
|
||||
`}</style>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
.body
|
||||
padding 0 16px 16px
|
18
src/client/components/dzeio/Box/BoxBody/index.tsx
Normal file
18
src/client/components/dzeio/Box/BoxBody/index.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import React from 'react'
|
||||
import css from './BoxBody.module.styl'
|
||||
import { buildClassName } from '@cp/dzeio/Util'
|
||||
|
||||
|
||||
interface Props {
|
||||
noPadding?: boolean
|
||||
}
|
||||
|
||||
export default class BoxBody extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<div className={buildClassName([css.body, !this.props.noPadding])}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
@import "../../config.styl"
|
||||
|
||||
.header
|
||||
padding 16px
|
||||
|
||||
.delimiter
|
||||
border-bottom 2px solid grey
|
||||
padding-bottom 2px
|
||||
|
||||
.img
|
||||
border-top-left-radius 4px
|
||||
border-top-right-radius 4px
|
||||
|
||||
.title
|
||||
font-weight bold
|
||||
font-size rem(20)
|
||||
margin 0 0 8px
|
||||
|
||||
.subtitle
|
||||
font-size rem(14)
|
||||
margin 0
|
55
src/client/components/dzeio/Box/BoxHeader/index.tsx
Normal file
55
src/client/components/dzeio/Box/BoxHeader/index.tsx
Normal file
@ -0,0 +1,55 @@
|
||||
import React from 'react'
|
||||
|
||||
import { buildClassName } from '../../Util'
|
||||
import css from './BoxHeader.module.styl'
|
||||
import Row from '@cp/dzeio/Row'
|
||||
import Col from '@cp/dzeio/Col'
|
||||
|
||||
|
||||
export interface Props {
|
||||
title?: string
|
||||
titleColSize?: number
|
||||
subtitle?: string
|
||||
delimiter?: boolean
|
||||
titleClassName?: string
|
||||
// image?: ImageProps
|
||||
}
|
||||
|
||||
export default class BoxHeader extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<>
|
||||
{/* {this.props.image && (
|
||||
<Image {...this.props.image} />
|
||||
)} */}
|
||||
<div className={buildClassName(
|
||||
[css.header],
|
||||
[css.delimiter, this.props.delimiter]
|
||||
)}>
|
||||
<Row>
|
||||
<Col size={this.props.titleColSize as 1 || 8}>
|
||||
<p className={buildClassName(css.title, this.props.titleClassName)}>{this.props.title}</p>
|
||||
<p className={css.subtitle}>{this.props.subtitle}</p>
|
||||
</Col>
|
||||
<Col>
|
||||
<Row justify="flex-end">
|
||||
{this.props.children}
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Header
|
||||
delimiter?: boolean
|
||||
picture?: string // url
|
||||
category?: string // subtitle but above title
|
||||
title string
|
||||
subtitle string
|
||||
center?: boolean // if Center children is not used
|
||||
children?: content
|
||||
*/
|
@ -0,0 +1,22 @@
|
||||
@import "../../config.styl"
|
||||
|
||||
.box
|
||||
background white
|
||||
border-radius 8px
|
||||
box-shadow 0px 2px 4px 0px rgba(black, .33)
|
||||
transition all $transition
|
||||
color black
|
||||
|
||||
.outline
|
||||
border 2px solid #E0E0E0
|
||||
box-shadow none
|
||||
transition border-color $transition
|
||||
|
||||
&:hover
|
||||
border-color darken(@border[2], 20%)
|
||||
|
||||
@media (prefers-color-scheme dark)
|
||||
.box
|
||||
background black
|
||||
.outline
|
||||
border-color #1F1F1F
|
32
src/client/components/dzeio/Box/BoxWrapper/index.tsx
Normal file
32
src/client/components/dzeio/Box/BoxWrapper/index.tsx
Normal file
@ -0,0 +1,32 @@
|
||||
import React from 'react'
|
||||
|
||||
import css from './BoxWrapper.module.styl'
|
||||
import { buildClassName } from '@cp/dzeio/Util'
|
||||
|
||||
interface Props extends React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> {
|
||||
outline?: boolean
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default class BoxWrapper extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<div {...this.props}
|
||||
className={buildClassName(
|
||||
css.box,
|
||||
this.props.className,
|
||||
[css.outline, this.props.outline]
|
||||
)}
|
||||
>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Wrapper extends div
|
||||
|
||||
Body
|
||||
noPadding?: boolean
|
||||
*/
|
10
src/client/components/dzeio/Box/index.tsx
Normal file
10
src/client/components/dzeio/Box/index.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import BoxWrapper from './BoxWrapper'
|
||||
import BoxHeader from './BoxHeader'
|
||||
import BoxBody from './BoxBody'
|
||||
|
||||
|
||||
export {
|
||||
BoxWrapper,
|
||||
BoxHeader,
|
||||
BoxBody
|
||||
}
|
201
src/client/components/dzeio/Button/Button.module.styl
Normal file
201
src/client/components/dzeio/Button/Button.module.styl
Normal file
@ -0,0 +1,201 @@
|
||||
@import '../config'
|
||||
|
||||
.button
|
||||
font-size rem(16)
|
||||
position relative
|
||||
transition all $transition
|
||||
font-weight 600
|
||||
line-height 1.5
|
||||
display inline-flex
|
||||
padding 10px 20px
|
||||
margin 8px 8px 0 8px
|
||||
cursor pointer
|
||||
align-items center
|
||||
text-align center
|
||||
border-radius 4px
|
||||
border none
|
||||
justify-content center
|
||||
color white
|
||||
background-color $default
|
||||
|
||||
// Chrome Specific
|
||||
outline none
|
||||
|
||||
// Link specific
|
||||
text-decoration none
|
||||
|
||||
&.nomargintop
|
||||
margin-top 0
|
||||
|
||||
&.outline
|
||||
border 2px solid @background-color
|
||||
padding 8px 18px // @padding - @border
|
||||
background transparent
|
||||
color @background-color
|
||||
|
||||
&:hover
|
||||
&:active
|
||||
&:focus
|
||||
color @color
|
||||
|
||||
&:hover
|
||||
background-color @background-color
|
||||
transform translateY(-2px)
|
||||
box-shadow 0 4px 4px rgba(@background-color,.2)
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
background-color darken(@background-color, 30%)
|
||||
|
||||
&.large
|
||||
padding 15px 30px
|
||||
font-size rem(20)
|
||||
|
||||
&.outline
|
||||
padding 13px 28px // @padding - @border
|
||||
|
||||
&.small
|
||||
padding 5px 10px
|
||||
font-size rem(14)
|
||||
|
||||
&.outline
|
||||
padding 3px 8px // @padding - @border
|
||||
|
||||
&.block
|
||||
display flex
|
||||
width 100%
|
||||
margin 0
|
||||
margin-top 8px
|
||||
|
||||
&:disabled
|
||||
background #E0E0E0 !important
|
||||
color #B0B0B0 !important
|
||||
transform none !important
|
||||
box-shadow none !important
|
||||
cursor initial
|
||||
|
||||
&.loading
|
||||
color transparent !important
|
||||
position relative
|
||||
pointer-events none
|
||||
|
||||
&::after
|
||||
content ""
|
||||
display block
|
||||
border white 2px solid
|
||||
border-color transparent transparent white white
|
||||
width 1em
|
||||
position absolute
|
||||
top calc(50% - (1em / 2))
|
||||
left calc(50% - (1em / 2))
|
||||
border-radius 100%
|
||||
height 1em
|
||||
box-sizing inherit
|
||||
animation ButtonLoading 1s infinite linear
|
||||
|
||||
|
||||
|
||||
.textInner
|
||||
margin-left 8px
|
||||
|
||||
.primary
|
||||
background-color $primary
|
||||
&.outline
|
||||
color @background-color
|
||||
border-color @background-color
|
||||
|
||||
&:hover
|
||||
background-color @background-color
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
background-color darken(@background-color, 30%)
|
||||
|
||||
&.loading::after
|
||||
border-color transparent transparent @background-color @background-color
|
||||
|
||||
.secondary
|
||||
background-color $secondary
|
||||
color black
|
||||
&.outline
|
||||
color @color
|
||||
border-color @background-color
|
||||
|
||||
&:hover
|
||||
background-color @background-color
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
background-color darken(@background-color, 30%)
|
||||
|
||||
&.loading::after
|
||||
border-color transparent transparent @color @color
|
||||
.info
|
||||
background-color $info
|
||||
&.outline
|
||||
color @background-color
|
||||
border-color @background-color
|
||||
|
||||
&:hover
|
||||
background-color @background-color
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
background-color darken(@background-color, 30%)
|
||||
|
||||
&.loading::after
|
||||
border-color transparent transparent @background-color @background-color
|
||||
.success
|
||||
background-color $success
|
||||
&.outline
|
||||
color @background-color
|
||||
border-color @background-color
|
||||
|
||||
&:hover
|
||||
background-color @background-color
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
background-color darken(@background-color, 30%)
|
||||
|
||||
&.loading::after
|
||||
border-color transparent transparent @background-color @background-color
|
||||
.danger
|
||||
background-color $danger
|
||||
|
||||
&.outline
|
||||
color @background-color
|
||||
border-color @background-color
|
||||
|
||||
&:hover
|
||||
background-color @background-color
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
background-color darken(@background-color, 30%)
|
||||
|
||||
&.loading::after
|
||||
border-color transparent transparent @background-color @background-color
|
||||
.warning
|
||||
background-color $warning
|
||||
|
||||
&.outline
|
||||
color @background-color
|
||||
border-color @background-color
|
||||
|
||||
&:hover
|
||||
background-color @background-color
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
background-color darken(@background-color, 30%)
|
||||
|
||||
&.loading::after
|
||||
border-color transparent transparent @background-color @background-color
|
||||
|
||||
@keyframes ButtonLoading
|
||||
0%
|
||||
transform rotate(0)
|
||||
|
||||
100%
|
||||
transform rotate(365deg)
|
67
src/client/components/dzeio/Button/index.tsx
Normal file
67
src/client/components/dzeio/Button/index.tsx
Normal file
@ -0,0 +1,67 @@
|
||||
import React, { FC } from 'react'
|
||||
import Link from '../Link'
|
||||
import { ColorType, IconProps } from '../interfaces'
|
||||
import { buildClassName } from '../Util'
|
||||
import Image from '../Image'
|
||||
|
||||
import css from './Button.module.styl'
|
||||
|
||||
interface Props {
|
||||
outline?: boolean
|
||||
nomargintop?: boolean
|
||||
color?: ColorType
|
||||
children?: React.ReactNode
|
||||
icon?: FC<IconProps> | string
|
||||
size?: 'large' | 'small' | 'block'
|
||||
href?: string
|
||||
as?: string
|
||||
disabled?: boolean
|
||||
loading?: boolean
|
||||
onClick?: (event: React.MouseEvent<HTMLButtonElement|HTMLAnchorElement, MouseEvent>) => void
|
||||
}
|
||||
|
||||
export default class Button extends React.Component<Props> {
|
||||
|
||||
public render = () => {
|
||||
|
||||
let inner: any = this.props.children
|
||||
|
||||
if (!this.props.loading && this.props.icon) {
|
||||
const Icon = this.props.icon
|
||||
inner = (
|
||||
<>
|
||||
{typeof Icon === 'string' ? (
|
||||
<Image src={Icon} max={{ height: 16, width: 16 }} />
|
||||
) : (
|
||||
<Icon size={16} />
|
||||
)}
|
||||
{this.props.children && (
|
||||
<span className={css.textInner}>{this.props.children}</span>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const classes = buildClassName(
|
||||
[css.button],
|
||||
[css[this.props.color as string], this.props.color],
|
||||
[css.outline, this.props.outline],
|
||||
[css[this.props.size as string], this.props.size],
|
||||
[css.nomargintop, this.props.nomargintop],
|
||||
[css.loading, this.props.loading]
|
||||
)
|
||||
|
||||
if (this.props.href) {
|
||||
return (
|
||||
<Link href={this.props.href} as={this.props.as} className={buildClassName([classes], [css.disabled, this.props.disabled])}>
|
||||
{inner}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<button onClick={this.props.onClick} disabled={this.props.disabled} className={classes}>{inner}</button>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
190
src/client/components/dzeio/Checkbox/Checkbox.module.styl
Normal file
190
src/client/components/dzeio/Checkbox/Checkbox.module.styl
Normal file
@ -0,0 +1,190 @@
|
||||
@import "../config.styl"
|
||||
|
||||
$backColor = #757575
|
||||
|
||||
.label
|
||||
position relative
|
||||
display flex
|
||||
padding-left 8px
|
||||
margin 8px
|
||||
user-select none
|
||||
|
||||
span
|
||||
top 0
|
||||
left 0
|
||||
width 20px
|
||||
height @width
|
||||
position absolute
|
||||
box-shadow inset 0 0 0 2px $backColor
|
||||
border-radius 2px
|
||||
transition all $transition
|
||||
|
||||
&::after
|
||||
border-radius 20px
|
||||
position absolute
|
||||
transition all $transition
|
||||
background $default
|
||||
|
||||
svg
|
||||
transition $transition
|
||||
transform scale(0)
|
||||
color transparent
|
||||
margin 2px
|
||||
|
||||
input
|
||||
visibility hidden
|
||||
width 20px
|
||||
height @width
|
||||
margin 0
|
||||
&:checked + span
|
||||
background rgba($default, .5)
|
||||
box-shadow inset 0 0 0 2px $default
|
||||
|
||||
svg
|
||||
color white
|
||||
transform scale(1)
|
||||
|
||||
|
||||
&:hover
|
||||
span
|
||||
box-shadow inset 0 0 0 2px black
|
||||
|
||||
.radio
|
||||
margin-left 18px // Margin + margin for Circle
|
||||
span
|
||||
border-radius 20px
|
||||
|
||||
&::after
|
||||
content " "
|
||||
top 5px
|
||||
left 5px
|
||||
width 10px
|
||||
height @width
|
||||
transform scale(0)
|
||||
|
||||
input:checked + span::after
|
||||
transform scale(1)
|
||||
background white
|
||||
|
||||
.switch
|
||||
padding 2px 0 2px 10px // 2px base padding 10px circle padding
|
||||
|
||||
&:hover span
|
||||
box-shadow none
|
||||
|
||||
&::after
|
||||
background black
|
||||
|
||||
span
|
||||
width 28px
|
||||
height 14px
|
||||
border-radius 20px
|
||||
top 50%
|
||||
box-shadow none
|
||||
background rgba($backColor, .5)
|
||||
transform translateY(-50%)
|
||||
|
||||
&::after
|
||||
content " "
|
||||
top 50%
|
||||
transform translate(-50%, -50%)
|
||||
left 0
|
||||
background $backColor
|
||||
width 20px
|
||||
height @width
|
||||
|
||||
input
|
||||
margin 0 8px
|
||||
width 20px
|
||||
|
||||
&:checked + span
|
||||
box-shadow none
|
||||
|
||||
&::after
|
||||
left 100%
|
||||
transform translate(-50%, -50%)
|
||||
background $default
|
||||
|
||||
.primary
|
||||
$color = $primary
|
||||
|
||||
input:checked + span
|
||||
background rgba($color, .5)
|
||||
box-shadow inset 0 0 0 2px $color
|
||||
|
||||
&::after
|
||||
background $color
|
||||
|
||||
&.switch
|
||||
input:checked + span
|
||||
box-shadow none
|
||||
|
||||
.secondary
|
||||
$color = $secondary
|
||||
|
||||
input:checked + span
|
||||
background rgba($color, .5)
|
||||
box-shadow inset 0 0 0 2px $color
|
||||
|
||||
&::after
|
||||
background $color
|
||||
|
||||
&.switch
|
||||
input:checked + span
|
||||
box-shadow none
|
||||
|
||||
.info
|
||||
$color = $info
|
||||
|
||||
input:checked + span
|
||||
background rgba($color, .5)
|
||||
box-shadow inset 0 0 0 2px $color
|
||||
|
||||
&::after
|
||||
background $color
|
||||
|
||||
&.switch
|
||||
input:checked + span
|
||||
box-shadow none
|
||||
|
||||
.success
|
||||
$color = $success
|
||||
|
||||
input:checked + span
|
||||
background rgba($color, .5)
|
||||
box-shadow inset 0 0 0 2px $color
|
||||
|
||||
&::after
|
||||
background $color
|
||||
|
||||
&.switch
|
||||
input:checked + span
|
||||
box-shadow none
|
||||
|
||||
.danger
|
||||
$color = $danger
|
||||
|
||||
input:checked + span
|
||||
background rgba($color, .5)
|
||||
box-shadow inset 0 0 0 2px $color
|
||||
|
||||
&::after
|
||||
background $color
|
||||
|
||||
&.switch
|
||||
input:checked + span
|
||||
box-shadow none
|
||||
|
||||
.warning
|
||||
$color = $warning
|
||||
|
||||
input:checked + span
|
||||
background rgba($color, .5)
|
||||
box-shadow inset 0 0 0 2px $color
|
||||
|
||||
&::after
|
||||
background $color
|
||||
|
||||
&.switch
|
||||
input:checked + span
|
||||
box-shadow none
|
50
src/client/components/dzeio/Checkbox/index.tsx
Normal file
50
src/client/components/dzeio/Checkbox/index.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
import React from 'react'
|
||||
import { Check } from 'react-feather'
|
||||
import { buildClassName } from '../Util'
|
||||
|
||||
import { ColorType } from '../interfaces'
|
||||
import css from './Checkbox.module.styl'
|
||||
|
||||
interface Props extends React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> {
|
||||
label?: string
|
||||
id: string
|
||||
type?: undefined
|
||||
radio?: boolean
|
||||
switch?: boolean
|
||||
color?: ColorType
|
||||
}
|
||||
|
||||
export default class Checkbox extends React.Component<Props> {
|
||||
|
||||
|
||||
public render() {
|
||||
const props: Props = Object.assign({}, this.props)
|
||||
delete props.label
|
||||
delete props.type
|
||||
delete props.color
|
||||
delete props.switch
|
||||
delete props.radio
|
||||
|
||||
const realType = this.props.radio ? 'radio' : 'checkbox'
|
||||
|
||||
return (
|
||||
<label htmlFor={this.props.id} className={buildClassName(
|
||||
[css.label],
|
||||
[css.radio, realType === 'radio'],
|
||||
[css.switch, this.props.switch],
|
||||
[css[this.props.color as string], this.props.color]
|
||||
)}>
|
||||
<input {...props}
|
||||
type={realType}
|
||||
/>
|
||||
<span>
|
||||
{realType === 'checkbox' && ! this.props.switch && (
|
||||
<Check strokeWidth={4} size={16}/>
|
||||
)}
|
||||
</span>
|
||||
{this.props.label}
|
||||
</label>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
5
src/client/components/dzeio/Code/Code.module.styl
Normal file
5
src/client/components/dzeio/Code/Code.module.styl
Normal file
@ -0,0 +1,5 @@
|
||||
.code
|
||||
font-family 'source code pro', monospace
|
||||
background #E8EAF6
|
||||
padding 4px 8px
|
||||
border-radius 8px
|
28
src/client/components/dzeio/Code/index.tsx
Normal file
28
src/client/components/dzeio/Code/index.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import React from 'react'
|
||||
|
||||
import css from './Code.module.styl'
|
||||
|
||||
interface Props {
|
||||
block?: boolean
|
||||
}
|
||||
|
||||
export default class Code extends React.Component<Props> {
|
||||
|
||||
public render = () => {
|
||||
const code = (
|
||||
<code className={css.code}>
|
||||
{this.props.children}
|
||||
</code>
|
||||
)
|
||||
if (!this.props.block) {
|
||||
return code
|
||||
}
|
||||
|
||||
return (
|
||||
<pre>
|
||||
{code}
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
48
src/client/components/dzeio/Col/Col.module.styl
Normal file
48
src/client/components/dzeio/Col/Col.module.styl
Normal file
@ -0,0 +1,48 @@
|
||||
@import "../config"
|
||||
|
||||
|
||||
|
||||
.col
|
||||
max-width 100%
|
||||
flex-basis 0
|
||||
flex-grow 1
|
||||
padding $gapSize 0 0 $gapSize
|
||||
|
||||
&.nogrow
|
||||
max-width intial
|
||||
flex-grow 0
|
||||
flex-basis initial
|
||||
|
||||
for i in (1...$colCount+1)
|
||||
.col-{i}
|
||||
flex 0 0 ((i / 12) * 100)%
|
||||
min-width ((i / 12) * 100)%
|
||||
|
||||
if i != $colCount
|
||||
.offset-{i}
|
||||
margin-left ((i / 12) * 100)% + (i * $gapSize + $gapSize)
|
||||
|
||||
@media (max-width $tablet)
|
||||
.col.tabletGrow
|
||||
flex-grow 1
|
||||
|
||||
for i in (1...$colCountTablet+1)
|
||||
.col-tablet-{i}
|
||||
flex 0 0 ((i / $colCountTablet) * 100)%
|
||||
min-width ((i / $colCountTablet) * 100)%
|
||||
|
||||
if i != $colCountTablet
|
||||
.offset-tablet-{i}
|
||||
margin-left ((i / $colCountTablet) * 100)% + (i * $gapSize - $gapSize)
|
||||
|
||||
@media (max-width $mobile)
|
||||
.col.mobileGrow
|
||||
flex-grow 1
|
||||
|
||||
for i in (1...$colCountMobile+1)
|
||||
.col-mobile-{i}
|
||||
flex 0 0 ((i / $colCountMobile) * 100)%
|
||||
min-width ((i / $colCountMobile) * 100)%
|
||||
if i != $colCountMobile
|
||||
.offset-tablet-{i}
|
||||
margin-left ((i / $colCountMobile) * 100)% + (i * $gapSize - $gapSize)
|
12
src/client/components/dzeio/Col/DebugCols.module.styl
Normal file
12
src/client/components/dzeio/Col/DebugCols.module.styl
Normal file
@ -0,0 +1,12 @@
|
||||
.row
|
||||
position fixed
|
||||
top 0
|
||||
left 0
|
||||
height 100%
|
||||
width 100%
|
||||
z-index 10000
|
||||
pointer-events none
|
||||
|
||||
.col > div
|
||||
background rgba(red, .2)
|
||||
height 100%
|
72
src/client/components/dzeio/Col/DebugCols.tsx
Normal file
72
src/client/components/dzeio/Col/DebugCols.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import React from 'react'
|
||||
import Row from '../Row'
|
||||
|
||||
import css from './DebugCols.module.styl'
|
||||
|
||||
import Col from '.'
|
||||
|
||||
enum Breakpoint {
|
||||
MOBILE,
|
||||
TABLET,
|
||||
COMPUT
|
||||
}
|
||||
|
||||
interface States {
|
||||
breakpoint: Breakpoint
|
||||
}
|
||||
|
||||
|
||||
export default class DebugCols extends React.Component<unknown, States> {
|
||||
|
||||
public state: States = {
|
||||
breakpoint: Breakpoint.COMPUT
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.onResize()
|
||||
window.addEventListener('resize', this.onResize)
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.onResize)
|
||||
}
|
||||
|
||||
public render = () => (
|
||||
<Row className={css.row}>
|
||||
<Col size={1} tabletSize={1} mobileSize={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} tabletSize={1} mobileSize={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} tabletSize={1} mobileSize={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} tabletSize={1} mobileSize={1} className={css.col}><div></div></Col>
|
||||
{this.state.breakpoint !== Breakpoint.MOBILE && (
|
||||
<>
|
||||
{this.state.breakpoint !== Breakpoint.TABLET && (
|
||||
<>
|
||||
<Col size={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} className={css.col}><div></div></Col>
|
||||
</>
|
||||
)}
|
||||
<Col size={1} tabletSize={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} tabletSize={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} tabletSize={1} className={css.col}><div></div></Col>
|
||||
<Col size={1} tabletSize={1} className={css.col}><div></div></Col>
|
||||
</>
|
||||
)}
|
||||
</Row>
|
||||
)
|
||||
|
||||
private onResize = async () => {
|
||||
const currentBreakpoint =
|
||||
window.innerWidth <= 768 ?
|
||||
Breakpoint.MOBILE :
|
||||
window.innerWidth <= 1200 ?
|
||||
Breakpoint.TABLET :
|
||||
Breakpoint.COMPUT
|
||||
const hasChanged = currentBreakpoint !== this.state.breakpoint
|
||||
if (hasChanged) {
|
||||
this.setState({ breakpoint: currentBreakpoint })
|
||||
}
|
||||
}
|
||||
|
||||
}
|
49
src/client/components/dzeio/Col/index.tsx
Normal file
49
src/client/components/dzeio/Col/index.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import React from 'react'
|
||||
import { buildClassName } from '../Util'
|
||||
import css from './Col.module.styl'
|
||||
|
||||
interface Props {
|
||||
size?: 1|2|3|4|5|6|7|8|9|10|11|12
|
||||
offset?: 1|2|3|4|5|6|7|8|9|10|11
|
||||
children?: React.ReactNode
|
||||
className?: string
|
||||
nogrow?: boolean
|
||||
|
||||
// Tablet related
|
||||
tabletSize?: 1|2|3|4|5|6|7|8
|
||||
tabletoffset?: 1|2|3|4|5|6|7
|
||||
tabletGrow?: boolean
|
||||
|
||||
|
||||
// Mobile related
|
||||
mobileSize?: 1|2|3|4
|
||||
mobileoffset?: 1|2|3
|
||||
mobileGrow?: boolean
|
||||
}
|
||||
|
||||
export default class Col extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<div className={buildClassName(
|
||||
css.col,
|
||||
|
||||
// Normal
|
||||
[css[`col-${this.props.size}`], this.props.size],
|
||||
[css[`offset-${this.props.offset}`], this.props.offset],
|
||||
|
||||
// Tablet
|
||||
[css[`col-tablet-${this.props.tabletSize}`], this.props.tabletSize],
|
||||
[css[`offset-tablet-${this.props.tabletoffset}`], this.props.tabletoffset],
|
||||
|
||||
// Mobile
|
||||
[css[`col-mobile-${this.props.mobileSize}`], this.props.mobileSize],
|
||||
[css[`offset-mobile-${this.props.mobileoffset}`], this.props.mobileoffset],
|
||||
[css.nogrow, this.props.nogrow],
|
||||
[css.mobileGrow, this.props.mobileGrow],
|
||||
this.props.className
|
||||
)}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
.container
|
||||
padding 16px
|
19
src/client/components/dzeio/Container/index.tsx
Normal file
19
src/client/components/dzeio/Container/index.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import React from 'react'
|
||||
import { buildClassName } from '../Util'
|
||||
|
||||
import css from './Container.module.styl'
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default class Container extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<div className={buildClassName(css.container, this.props.className)}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
18
src/client/components/dzeio/Fieldset/Fieldset.module.styl
Normal file
18
src/client/components/dzeio/Fieldset/Fieldset.module.styl
Normal file
@ -0,0 +1,18 @@
|
||||
@import '../config.styl'
|
||||
|
||||
.fieldset
|
||||
border-radius 8px
|
||||
border 2px solid grey
|
||||
transition all $transition
|
||||
margin 0
|
||||
|
||||
> legend
|
||||
font-weight 600
|
||||
transition all $transition
|
||||
padding 0 4px
|
||||
|
||||
&:hover
|
||||
border-color black
|
||||
|
||||
> legend
|
||||
color $default
|
21
src/client/components/dzeio/Fieldset/index.tsx
Normal file
21
src/client/components/dzeio/Fieldset/index.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import React from 'react'
|
||||
|
||||
import css from './Fieldset.module.styl'
|
||||
|
||||
interface Props {
|
||||
title?: string
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export default class Fieldset extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<fieldset className={css.fieldset}>
|
||||
{this.props.title && (
|
||||
<legend>{this.props.title}</legend>
|
||||
)}
|
||||
{this.props.children}
|
||||
</fieldset>
|
||||
)
|
||||
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
@import "../config"
|
||||
|
||||
$transparent = 75%
|
||||
|
||||
.back
|
||||
transition all $transition
|
||||
color white
|
||||
background linear-gradient(to left, $default, transparentify($default, $transparent))
|
||||
|
||||
.primary
|
||||
$color = $primary
|
||||
background linear-gradient(to left, $color, transparentify($color, $transparent))
|
||||
|
||||
.secondary
|
||||
$color = $secondary
|
||||
background linear-gradient(to left, $color, transparentify($color, $transparent))
|
||||
|
||||
.info
|
||||
$color = $info
|
||||
background linear-gradient(to left, $color, transparentify($color, $transparent))
|
||||
|
||||
.success
|
||||
$color = $success
|
||||
background linear-gradient(to left, $color, transparentify($color, $transparent))
|
||||
|
||||
.danger
|
||||
$color = $danger
|
||||
background linear-gradient(to left, $color, transparentify($color, $transparent))
|
||||
|
||||
.warning
|
||||
$color = $warning
|
||||
background linear-gradient(to left, $color, transparentify($color, $transparent))
|
21
src/client/components/dzeio/GradientBackground/index.tsx
Normal file
21
src/client/components/dzeio/GradientBackground/index.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import React from 'react'
|
||||
import { ColorType } from '../interfaces'
|
||||
|
||||
import { buildClassName } from '../Util'
|
||||
import css from './GradientBackground.module.styl'
|
||||
|
||||
interface Props {
|
||||
color?: ColorType
|
||||
className?: string
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export default class GradientBackground extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<div className={buildClassName([css.back], [css[this.props.color as string], this.props.color], [this.props.className])}>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
@ -2,8 +2,7 @@
|
||||
transition .3s
|
||||
object-fit contain
|
||||
z-index 2
|
||||
transition .3s
|
||||
|
||||
max-width 100%
|
||||
|
||||
&.ph1
|
||||
position fixed
|
||||
@ -25,10 +24,10 @@
|
||||
|
||||
&.after
|
||||
background #00000000
|
||||
/* height 100% */
|
||||
// height 100%
|
||||
box-sizing border-box
|
||||
position fixed
|
||||
/* width 100% */
|
||||
// width 100%
|
||||
z-index 0
|
||||
padding initial
|
||||
|
@ -1,7 +1,9 @@
|
||||
import React, { SyntheticEvent } from 'react'
|
||||
import css from '@smd/Image.module.styl'
|
||||
import React from 'react'
|
||||
import { buildClassName } from '../Util'
|
||||
|
||||
interface Props {
|
||||
import css from './Image.module.styl'
|
||||
|
||||
export interface ImageProps {
|
||||
defaultHeight?: number
|
||||
src?: string
|
||||
sources?: Array<string>
|
||||
@ -18,6 +20,15 @@ interface Props {
|
||||
width?: number|string
|
||||
}
|
||||
alt?: string
|
||||
classes?: string
|
||||
className?: string
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
enum images {
|
||||
JPEG = 'image/jpeg',
|
||||
XICON = 'image/x-icon',
|
||||
TIFF = 'image/tiff'
|
||||
}
|
||||
|
||||
const mimeTypes = {
|
||||
@ -25,22 +36,22 @@ const mimeTypes = {
|
||||
bmp: 'image/bmp',
|
||||
gif: 'image/gif',
|
||||
|
||||
ico: 'image/x-icon',
|
||||
cur: 'image/x-icon',
|
||||
ico: images.XICON,
|
||||
cur: images.XICON,
|
||||
|
||||
jpg: 'image/jpeg',
|
||||
jpeg: 'image/jpeg',
|
||||
jfif: 'image/jpeg',
|
||||
pjpeg: 'image/jpeg',
|
||||
pjp: 'image/jpeg',
|
||||
jpg: images.JPEG,
|
||||
jpeg: images.JPEG,
|
||||
jfif: images.JPEG,
|
||||
pjpeg: images.JPEG,
|
||||
pjp: images.JPEG,
|
||||
|
||||
png: 'image/png',
|
||||
svg: 'image/svg+xml',
|
||||
|
||||
tif: 'image/tiff',
|
||||
tiff: 'image/tiff',
|
||||
tif: images.TIFF,
|
||||
tiff: images.TIFF,
|
||||
|
||||
webp: 'image/webp',
|
||||
webp: 'image/webp'
|
||||
}
|
||||
|
||||
const getMimeType = (img: string) => {
|
||||
@ -48,9 +59,9 @@ const getMimeType = (img: string) => {
|
||||
return mimeTypes[arr[arr.length-1] as 'apng'] || mimeTypes.png
|
||||
}
|
||||
|
||||
type evType<T = HTMLImageElement> = SyntheticEvent<T, Event>
|
||||
type evType<T = HTMLImageElement> = React.SyntheticEvent<T, Event>
|
||||
|
||||
export default class Image extends React.Component<Props> {
|
||||
export default class Image extends React.Component<ImageProps> {
|
||||
|
||||
private ref: React.RefObject<HTMLImageElement> = React.createRef()
|
||||
private plchldr: React.RefObject<HTMLDivElement> = React.createRef()
|
||||
@ -78,7 +89,9 @@ export default class Image extends React.Component<Props> {
|
||||
this.onScroll()
|
||||
this.onResize()
|
||||
}
|
||||
if (this.isFullscreen) {this.onClick()}
|
||||
if (this.isFullscreen) {
|
||||
this.onClick()
|
||||
}
|
||||
}
|
||||
|
||||
public async componentWillUnmount() {
|
||||
@ -90,33 +103,35 @@ export default class Image extends React.Component<Props> {
|
||||
|
||||
public render() {
|
||||
const pic = (
|
||||
<picture ref={this.pic}>
|
||||
{this.props.sources && this.props.sources.map((el,index) => (
|
||||
<picture ref={this.pic} className={this.props.classes}>
|
||||
{this.props.sources && this.props.sources.map((el, index) => (
|
||||
<source key={index} srcSet={el} type={getMimeType(el)}/>
|
||||
))}
|
||||
<img
|
||||
className={css.image}
|
||||
className={buildClassName([css.image], [this.props.className])}
|
||||
ref={this.ref}
|
||||
src={this.props.src}
|
||||
onClick={this.props.canFullscreen && this.onClick || undefined}
|
||||
onClick={this.props.canFullscreen && this.onClick || this.props.onClick}
|
||||
onLoad={this.props.default && this.onLoad || undefined}
|
||||
onError={this.props.deleteOnError && this.onError || undefined}
|
||||
style={{
|
||||
width: this.props.default?.width,
|
||||
height: this.props.default?.height,
|
||||
maxHeight: this.props.max?.height,
|
||||
maxWidth: this.props.max?.width,
|
||||
maxWidth: this.props.max?.width
|
||||
}}
|
||||
alt={this.props.alt}
|
||||
/>
|
||||
</picture>
|
||||
)
|
||||
if (this.props.canFullscreen) {return (
|
||||
<div ref={this.parent}>
|
||||
<div ref={this.plchldr} className={css.none}></div>
|
||||
{pic}
|
||||
</div>
|
||||
)}
|
||||
if (this.props.canFullscreen) {
|
||||
return (
|
||||
<div ref={this.parent}>
|
||||
<div ref={this.plchldr} className={css.none}></div>
|
||||
{pic}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return pic
|
||||
}
|
||||
|
||||
@ -146,6 +161,9 @@ export default class Image extends React.Component<Props> {
|
||||
if (!this.ref.current || !this.props.canFullscreen || !this.plchldr.current) {
|
||||
return
|
||||
}
|
||||
if (this.props.onClick) {
|
||||
this.props.onClick()
|
||||
}
|
||||
|
||||
const i = this.ref.current
|
||||
const c = this.plchldr.current
|
||||
@ -161,7 +179,9 @@ export default class Image extends React.Component<Props> {
|
||||
i.classList.add(css.after)
|
||||
|
||||
setTimeout(() => {
|
||||
if (i.classList.contains(css.ph2) || i.classList.contains(css.ph1) || this.isFullscreen) {return}
|
||||
if (i.classList.contains(css.ph2) || i.classList.contains(css.ph1) || this.isFullscreen) {
|
||||
return
|
||||
}
|
||||
const w = this.valToPixel(this.props.width)
|
||||
const mh = this.valToPixel(this.props.max?.height)
|
||||
const mw = this.valToPixel(this.props.max?.width)
|
||||
@ -206,4 +226,5 @@ export default class Image extends React.Component<Props> {
|
||||
private w(...messages: any) {
|
||||
console.warn('[ Picture ]', ...messages)
|
||||
}
|
||||
|
||||
}
|
165
src/client/components/dzeio/Input/Input.module.styl
Normal file
165
src/client/components/dzeio/Input/Input.module.styl
Normal file
@ -0,0 +1,165 @@
|
||||
@import '../config'
|
||||
|
||||
.parent
|
||||
position relative
|
||||
margin 16px
|
||||
|
||||
label
|
||||
font-size 1rem
|
||||
font-weight 600
|
||||
color black
|
||||
display inline-block
|
||||
margin-bottom .5rem
|
||||
transition all $transition
|
||||
position absolute
|
||||
top 16px
|
||||
pointer-events none
|
||||
left 16px
|
||||
|
||||
svg
|
||||
position absolute
|
||||
color #AAA
|
||||
top 14px
|
||||
left 16px // input padding-left
|
||||
transition color $transition
|
||||
|
||||
~ label
|
||||
left 16px + 24px + 16px
|
||||
|
||||
select
|
||||
appearance none
|
||||
|
||||
input
|
||||
select
|
||||
padding 14px 16px
|
||||
max-width 100%
|
||||
height 56px
|
||||
border 2px solid rgba(black, .3)
|
||||
border-radius 4px
|
||||
box-sizing border-box
|
||||
font-size .875rem
|
||||
outline none
|
||||
background transparent
|
||||
transition all $transition
|
||||
color black
|
||||
&:hover
|
||||
border-color black
|
||||
|
||||
+ svg
|
||||
color black
|
||||
|
||||
&:not(:placeholder-shown)
|
||||
&:focus
|
||||
&:not([placeholder=" "])
|
||||
~ label
|
||||
top -8px
|
||||
left 16px - 4px // .input/padding-left label/padding-left
|
||||
background white
|
||||
padding 0 4px
|
||||
|
||||
&:invalid
|
||||
border-color $danger
|
||||
|
||||
~ label
|
||||
color @border-color
|
||||
|
||||
~ svg
|
||||
color @border-color
|
||||
&:focus
|
||||
border-color $default
|
||||
|
||||
~ label
|
||||
color @border-color
|
||||
|
||||
~ svg
|
||||
color @border-color
|
||||
|
||||
&.primary
|
||||
border-color $primary
|
||||
|
||||
~ label
|
||||
color @border-color
|
||||
|
||||
~ svg
|
||||
color @border-color
|
||||
|
||||
&.secondary
|
||||
border-color $secondary
|
||||
|
||||
~ label
|
||||
color @border-color
|
||||
|
||||
~ svg
|
||||
color @border-color
|
||||
|
||||
&.info
|
||||
border-color $info
|
||||
|
||||
~ label
|
||||
color @border-color
|
||||
|
||||
~ svg
|
||||
color @border-color
|
||||
|
||||
&.success
|
||||
border-color $success
|
||||
|
||||
~ label
|
||||
color @border-color
|
||||
|
||||
~ svg
|
||||
color @border-color
|
||||
|
||||
&.danger
|
||||
border-color $danger
|
||||
|
||||
~ label
|
||||
color @border-color
|
||||
|
||||
~ svg
|
||||
color @border-color
|
||||
|
||||
&.warning
|
||||
border-color $warning
|
||||
|
||||
~ label
|
||||
color @border-color
|
||||
|
||||
~ svg
|
||||
color @border-color
|
||||
|
||||
&.hasIcon
|
||||
padding-left 16px + 24px + 16px
|
||||
|
||||
&.filled
|
||||
border none
|
||||
background rgba(gray, .1)
|
||||
border-radius @border-radius @border-radius 0 0
|
||||
border-bottom 2px solid rgba(black,.4)
|
||||
|
||||
&:hover
|
||||
background rgba(gray, .2)
|
||||
|
||||
&:focus
|
||||
background rgba(gray, .3)
|
||||
|
||||
&:not(:placeholder-shown)
|
||||
&:focus
|
||||
&:not([placeholder=" "])
|
||||
~ label
|
||||
top 3px
|
||||
left 16px - 4px // .input/padding-left label/padding-left
|
||||
background transparent
|
||||
padding 0
|
||||
font-size .75rem
|
||||
~ svg ~ label
|
||||
left 16px + 24px + 16px // .input/padding-left label/padding-left
|
||||
|
||||
div
|
||||
display flex
|
||||
justify-content space-between
|
||||
padding 0 16px
|
||||
font-size .9em
|
||||
|
||||
&.block input
|
||||
width 100%
|
117
src/client/components/dzeio/Input/index.tsx
Normal file
117
src/client/components/dzeio/Input/index.tsx
Normal file
@ -0,0 +1,117 @@
|
||||
import React, { FC } from 'react'
|
||||
|
||||
import { ChevronDown } from 'react-feather'
|
||||
import { IconProps, ColorType } from '../interfaces'
|
||||
import { buildClassName } from '../Util'
|
||||
import css from './Input.module.styl'
|
||||
|
||||
interface Props extends React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> {
|
||||
id?: string
|
||||
label?: string
|
||||
icon?: FC<IconProps>
|
||||
helper?: string
|
||||
characterCount?: boolean
|
||||
inputRef?: React.RefObject<HTMLInputElement>
|
||||
selectRef?: React.RefObject<HTMLSelectElement>
|
||||
type?: 'color' | 'text' | 'date' | 'datetime-local' |
|
||||
'email' | 'file' | 'month' | 'number' | 'password' |
|
||||
'range' | 'search' | 'tel' | 'time' | 'url' | 'week' | 'select'
|
||||
maxLength?: number | undefined
|
||||
infinityText?: string
|
||||
filled?: boolean
|
||||
block?: boolean
|
||||
color?: ColorType
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export default class Input extends React.Component<Props> {
|
||||
|
||||
private charCountRef: React.RefObject<HTMLSpanElement> = React.createRef()
|
||||
|
||||
public componentDidMount() {
|
||||
this.updatecharCount()
|
||||
}
|
||||
|
||||
public render() {
|
||||
const props: Props = Object.assign({}, this.props)
|
||||
const Icon = this.props.icon
|
||||
delete props.label
|
||||
delete props.icon
|
||||
delete props.helper
|
||||
delete props.infinityText
|
||||
delete props.filled
|
||||
delete props.inputRef
|
||||
delete props.selectRef
|
||||
delete props.block
|
||||
delete props.color
|
||||
delete props.characterCount
|
||||
|
||||
return (
|
||||
<div
|
||||
className={buildClassName(
|
||||
[css.parent],
|
||||
[css.block, this.props.block]
|
||||
)}
|
||||
onChangeCapture={this.props.characterCount ? this.updatecharCount : undefined}
|
||||
>
|
||||
{this.props.type === 'select' ? (
|
||||
<select
|
||||
ref={this.props.selectRef}
|
||||
className={buildClassName(
|
||||
css.hasIcon,
|
||||
[css.filled, this.props.filled],
|
||||
[css[this.props.color as string], this.props.color]
|
||||
)}
|
||||
>
|
||||
{this.props.children}
|
||||
</select>
|
||||
) : (
|
||||
<input
|
||||
placeholder=" "
|
||||
ref={this.props.inputRef}
|
||||
{...props}
|
||||
className={buildClassName(
|
||||
[css.hasIcon, Icon],
|
||||
[css.filled, this.props.filled],
|
||||
[css[this.props.color as string], this.props.color]
|
||||
)}
|
||||
onInvalid={(ev) => ev.preventDefault()}
|
||||
/>
|
||||
)}
|
||||
{this.props.type === 'select' && (
|
||||
<ChevronDown />
|
||||
)}
|
||||
{Icon && (
|
||||
<Icon />
|
||||
)}
|
||||
{this.props.label && (
|
||||
<label className={css.label} htmlFor={this.props.id}>{this.props.label}</label>
|
||||
)}
|
||||
{(this.props.helper || this.props.characterCount) && (
|
||||
<div>
|
||||
<span>{this.props.helper}</span>
|
||||
<span ref={this.charCountRef}></span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private updatecharCount = async (event?: React.FormEvent<HTMLDivElement>) => {
|
||||
if (this.props.characterCount && this.charCountRef.current) {
|
||||
const max = this.props.maxLength || this.props.infinityText || 'Infinity'
|
||||
let currentCount = 0
|
||||
if (event) {
|
||||
currentCount = (event.target as HTMLInputElement).value.length
|
||||
} else {
|
||||
if (this.props.defaultValue) {
|
||||
currentCount = this.props.defaultValue.toString().length
|
||||
} else if (this.props.value) {
|
||||
currentCount = this.props.value.toString().length
|
||||
}
|
||||
}
|
||||
this.charCountRef.current.innerText = currentCount + ' / ' + max
|
||||
}
|
||||
}
|
||||
|
||||
}
|
3
src/client/components/dzeio/Link/Link.module.styl
Normal file
3
src/client/components/dzeio/Link/Link.module.styl
Normal file
@ -0,0 +1,3 @@
|
||||
.icon
|
||||
vertical-align sub
|
||||
margin 2px
|
40
src/client/components/dzeio/Link/index.tsx
Normal file
40
src/client/components/dzeio/Link/index.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import React from 'react'
|
||||
import NextLink from 'next/link'
|
||||
import { ExternalLink } from 'react-feather'
|
||||
|
||||
import css from './Link.module.styl'
|
||||
|
||||
interface Props {
|
||||
href: string
|
||||
as?: string
|
||||
children?: React.ReactNode
|
||||
className?: string
|
||||
}
|
||||
|
||||
export default class Link extends React.Component<Props> {
|
||||
|
||||
public render() {
|
||||
if (
|
||||
this.props.href.includes('://') ||
|
||||
this.props.href.startsWith('//')
|
||||
) {
|
||||
// external link
|
||||
return (
|
||||
<a
|
||||
className={this.props.className}
|
||||
href={this.props.href}
|
||||
rel="noreferrer nofollow"
|
||||
target="_blank"
|
||||
>
|
||||
{this.props.children}<ExternalLink size={16} className={css.icon} />
|
||||
</a>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<NextLink href={this.props.href} as={this.props.as}>
|
||||
<a className={this.props.className}>{this.props.children}</a>
|
||||
</NextLink>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
19
src/client/components/dzeio/Menu/Menu.module.styl
Normal file
19
src/client/components/dzeio/Menu/Menu.module.styl
Normal file
@ -0,0 +1,19 @@
|
||||
@import '../config'
|
||||
|
||||
.menu
|
||||
position absolute
|
||||
opacity 0
|
||||
background white
|
||||
pointer-events none
|
||||
border-radius 4px
|
||||
box-shadow 0 2px 4px 2px rgba(black, 25%)
|
||||
z-index 99
|
||||
transition opacity $transition
|
||||
a
|
||||
display block
|
||||
text-align center
|
||||
padding 16px
|
||||
|
||||
&.shown
|
||||
opacity 1
|
||||
pointer-events initial
|
25
src/client/components/dzeio/Menu/index.tsx
Normal file
25
src/client/components/dzeio/Menu/index.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
|
||||
import { buildClassName } from '../Util'
|
||||
import css from './Menu.module.styl'
|
||||
|
||||
interface Props {
|
||||
pos?: {top?: number, bottom?: number, left?: number, right?: number}
|
||||
content: Array<{name: string, href: string, as?: string}>
|
||||
show?: boolean
|
||||
}
|
||||
|
||||
export default class Menu extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<div className={buildClassName([css.menu], [css.shown, this.props.show])} style={this.props.pos}>
|
||||
{this.props.content.map((item, index) => (
|
||||
<Link key={index} href={item.href} as={item.as}>
|
||||
<a>{item.name}</a>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
52
src/client/components/dzeio/Navbar/Navbar.module.styl
Normal file
52
src/client/components/dzeio/Navbar/Navbar.module.styl
Normal file
@ -0,0 +1,52 @@
|
||||
@import "../config"
|
||||
|
||||
.navbar
|
||||
width 100%
|
||||
height 70px
|
||||
padding 8px 0
|
||||
position absolute
|
||||
top 0
|
||||
left 0
|
||||
border-bottom 1px solid white
|
||||
|
||||
> div
|
||||
height 100%
|
||||
|
||||
&.small
|
||||
padding-left 216px
|
||||
|
||||
.alignRight
|
||||
text-align right
|
||||
|
||||
.favicon img
|
||||
height 38px
|
||||
border-radius 8px
|
||||
border 2px solid white
|
||||
padding 2px
|
||||
background white
|
||||
width 38px
|
||||
|
||||
.userIcon img
|
||||
padding 0
|
||||
cursor pointer
|
||||
|
||||
.text
|
||||
display inline-block
|
||||
margin 0
|
||||
height 38px
|
||||
line-height 1
|
||||
font-weight bold
|
||||
font-size rem(20)
|
||||
padding 7px 0 11px 16px
|
||||
text-decoration none
|
||||
color white
|
||||
cursor pointer
|
||||
|
||||
.spacer
|
||||
height 70px
|
||||
|
||||
.icon
|
||||
padding 7px 16px
|
||||
color white
|
||||
box-sizing content-box
|
||||
cursor pointer
|
11
src/client/components/dzeio/Navbar/NavbarSpace.tsx
Normal file
11
src/client/components/dzeio/Navbar/NavbarSpace.tsx
Normal file
@ -0,0 +1,11 @@
|
||||
import React from 'react'
|
||||
|
||||
import css from './Navbar.module.styl'
|
||||
|
||||
export default class NavbarSpace extends React.Component {
|
||||
|
||||
public render = () => (
|
||||
<div className={css.spacer}></div>
|
||||
)
|
||||
|
||||
}
|
47
src/client/components/dzeio/Navbar/index.tsx
Normal file
47
src/client/components/dzeio/Navbar/index.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import React from 'react'
|
||||
import Link from 'next/link'
|
||||
import Row from '../Row'
|
||||
import Col from '../Col'
|
||||
import Button from '../Button'
|
||||
import Image from '../Image'
|
||||
|
||||
|
||||
import { buildClassName } from '../Util'
|
||||
import css from './Navbar.module.styl'
|
||||
|
||||
interface Props {
|
||||
links: Array<{href: string, txt: string}>
|
||||
}
|
||||
|
||||
export default class Navbar extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<nav className={buildClassName(css.navbar)}>
|
||||
<Row>
|
||||
<Col size={3} mobileSize={4}>
|
||||
<Row nomargin align="center">
|
||||
<Link href="/">
|
||||
<a aria-label="Homepage">
|
||||
<Image
|
||||
alt="Logo"
|
||||
src="/assets/logo.svg"
|
||||
max={{ height: 70-16 }}
|
||||
/>
|
||||
</a>
|
||||
</Link>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col>
|
||||
<Row nomargin justify="flex-end" align="center">
|
||||
<>
|
||||
{this.props.links.map((el, index) => (
|
||||
<Button key={index} nomargintop href={el.href}>{el.txt}</Button>
|
||||
))}
|
||||
</>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</nav>
|
||||
)
|
||||
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
$height = 45px
|
||||
|
||||
.top
|
||||
height $height
|
||||
.bottom
|
||||
margin-top - $height
|
20
src/client/components/dzeio/Overflow/index.tsx
Normal file
20
src/client/components/dzeio/Overflow/index.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import React from 'react'
|
||||
|
||||
import { buildClassName } from '../Util'
|
||||
import css from './Overflow.module.styl'
|
||||
|
||||
interface Props {
|
||||
bottom?: boolean
|
||||
top?: boolean
|
||||
}
|
||||
|
||||
export default class Overflow extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<div className={buildClassName(
|
||||
[css.bottom, this.props.bottom],
|
||||
[css.top, this.props.top]
|
||||
)}></div>
|
||||
)
|
||||
|
||||
}
|
14
src/client/components/dzeio/Popup/Popup.module.styl
Normal file
14
src/client/components/dzeio/Popup/Popup.module.styl
Normal file
@ -0,0 +1,14 @@
|
||||
.popup
|
||||
position fixed
|
||||
height 100%
|
||||
width 100%
|
||||
top 0
|
||||
left 0
|
||||
background rgba(black, .3)
|
||||
cursor pointer
|
||||
|
||||
.popupChild
|
||||
cursor initial
|
||||
|
||||
.exit
|
||||
cursor pointer
|
36
src/client/components/dzeio/Popup/index.tsx
Normal file
36
src/client/components/dzeio/Popup/index.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import React from 'react'
|
||||
import { X } from 'react-feather'
|
||||
import { BoxWrapper, BoxHeader, BoxBody } from '../Box'
|
||||
import { Props as HeaderProps } from '../Box/BoxHeader'
|
||||
import Row from '../Row'
|
||||
|
||||
import css from './Popup.module.styl'
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode
|
||||
onClose?: () => void
|
||||
header?: HeaderProps
|
||||
}
|
||||
|
||||
export default class Popup extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<Row onClick={this.parentClose} justify="center" align="center" className={css.popup}>
|
||||
<BoxWrapper className={css.popupChild}>
|
||||
<BoxHeader {...this.props.header}>
|
||||
<X onClick={this.props.onClose} className={css.exit} />
|
||||
</BoxHeader>
|
||||
<BoxBody>
|
||||
{this.props.children}
|
||||
</BoxBody>
|
||||
</BoxWrapper>
|
||||
</Row>
|
||||
)
|
||||
|
||||
private parentClose = (ev: React.MouseEvent<HTMLDivElement>) => {
|
||||
if ((ev.target as HTMLElement).classList.contains(css.popup) && this.props.onClose) {
|
||||
this.props.onClose()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
36
src/client/components/dzeio/Row/Row.module.styl
Normal file
36
src/client/components/dzeio/Row/Row.module.styl
Normal file
@ -0,0 +1,36 @@
|
||||
@import "../config"
|
||||
|
||||
.row
|
||||
display flex
|
||||
flex-wrap wrap
|
||||
|
||||
&:not(.nomargin)
|
||||
margin (0 - $gapSize) 0 0
|
||||
padding 0 $gapSize * 2 0 $gapSize
|
||||
|
||||
.row:not(.nomargin)
|
||||
padding 0
|
||||
margin (0 - $gapSize) 0 0 (0 - $gapSize)
|
||||
|
||||
.nowrap
|
||||
flex-wrap nowrap
|
||||
|
||||
.nogrow > *
|
||||
flex-grow 0
|
||||
|
||||
for dir in 'row-reverse' 'column' 'column-reverse'
|
||||
.direction-{dir}
|
||||
flex-direction unquote(dir)
|
||||
|
||||
@media (max-width: $mobile)
|
||||
for dir in 'row-reverse' 'column' 'column-reverse'
|
||||
.direction-mobile-{dir}
|
||||
flex-direction unquote(dir)
|
||||
|
||||
for just in 'flex-start' 'center' 'flex-end' 'space-between' 'space-around' 'space-evenly'
|
||||
.justify-{just}
|
||||
justify-content unquote(just)
|
||||
|
||||
for align in 'flex-start' 'center' 'flex-end' 'baseline'
|
||||
.align-{align}
|
||||
align-items unquote(align)
|
40
src/client/components/dzeio/Row/index.tsx
Normal file
40
src/client/components/dzeio/Row/index.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import React from 'react'
|
||||
|
||||
import { buildClassName } from '../Util'
|
||||
import css from './Row.module.styl'
|
||||
|
||||
interface Props {
|
||||
children?: React.ReactNode
|
||||
direction?: 'row-reverse' | 'column' | 'column-reverse'
|
||||
mobileDirection?: 'row-reverse' | 'column' | 'column-reverse'
|
||||
justify?: 'flex-start' | 'center' | 'flex-end' | 'space-between' | 'space-around' | 'space-evenly'
|
||||
align?: 'flex-start' | 'center' | 'flex-end' | 'baseline'
|
||||
nowrap?: boolean
|
||||
nogrow?: boolean
|
||||
className?: string
|
||||
nomargin?: boolean
|
||||
onClick?: (ev: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
|
||||
}
|
||||
|
||||
export default class Row extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<div
|
||||
className={buildClassName(
|
||||
css.row,
|
||||
[css[`direction-${this.props.direction}`], this.props.direction],
|
||||
[css[`direction-mobile-${this.props.mobileDirection}`], this.props.mobileDirection],
|
||||
[css[`justify-${this.props.justify}`], this.props.justify],
|
||||
[css[`align-${this.props.align}`], this.props.align],
|
||||
[css.nowrap, this.props.nowrap],
|
||||
[css.nogrow, this.props.nogrow],
|
||||
this.props.className,
|
||||
[css.nomargin, this.props.nomargin]
|
||||
)}
|
||||
onClick={this.props.onClick}
|
||||
>
|
||||
{this.props.children}
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
13
src/client/components/dzeio/Table/Table.module.styl
Normal file
13
src/client/components/dzeio/Table/Table.module.styl
Normal file
@ -0,0 +1,13 @@
|
||||
.table
|
||||
border-spacing 0
|
||||
border 2px solid #EEE
|
||||
border-radius 4px
|
||||
width 100%
|
||||
|
||||
td
|
||||
border-top 1px solid #EEE
|
||||
|
||||
th
|
||||
td
|
||||
padding 8px
|
||||
text-align left
|
15
src/client/components/dzeio/Table/index.tsx
Normal file
15
src/client/components/dzeio/Table/index.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import React from 'react'
|
||||
|
||||
import css from './Table.module.styl'
|
||||
|
||||
interface Props {
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export default class Table extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<table className={css.table}>{this.props.children}</table>
|
||||
)
|
||||
|
||||
}
|
137
src/client/components/dzeio/Tag/Tag.module.styl
Normal file
137
src/client/components/dzeio/Tag/Tag.module.styl
Normal file
@ -0,0 +1,137 @@
|
||||
@import '../config'
|
||||
|
||||
.tag
|
||||
padding 8px 12px
|
||||
border-radius 8px
|
||||
margin-left 8px
|
||||
height 32px
|
||||
line-height 1
|
||||
|
||||
background #EEE
|
||||
outline none
|
||||
&:hover
|
||||
background darken(#EEE, 10%)
|
||||
&:focus
|
||||
background darken(#EEE, 20%)
|
||||
|
||||
.outline
|
||||
border 2px solid #AAA
|
||||
padding 6px 10px
|
||||
background transparent
|
||||
&:hover
|
||||
background rgba(#AAA, .5)
|
||||
&:focus
|
||||
background rgba(#AAA, .7)
|
||||
|
||||
.primary
|
||||
$color = $primary
|
||||
color white
|
||||
background $color
|
||||
&:hover
|
||||
background lighten($color, 30%)
|
||||
&:focus
|
||||
background lighten($color, 15%)
|
||||
|
||||
&.outline
|
||||
color black
|
||||
border 2px solid $color
|
||||
background transparent
|
||||
&:hover
|
||||
color white
|
||||
background rgba($color, .5)
|
||||
&:focus
|
||||
color white
|
||||
background rgba($color, .7)
|
||||
.secondary
|
||||
$color = $secondary
|
||||
background $color
|
||||
&:hover
|
||||
background lighten($color, 30%)
|
||||
&:focus
|
||||
background lighten($color, 15%)
|
||||
&.outline
|
||||
color white
|
||||
border 2px solid $color
|
||||
background transparent
|
||||
&:hover
|
||||
color black
|
||||
background rgba($color, .5)
|
||||
&:focus
|
||||
color black
|
||||
background rgba($color, .7)
|
||||
|
||||
.info
|
||||
$color = $info
|
||||
color white
|
||||
background $color
|
||||
&:hover
|
||||
background lighten($color, 30%)
|
||||
&:focus
|
||||
background lighten($color, 15%)
|
||||
&.outline
|
||||
color black
|
||||
border 2px solid $color
|
||||
background transparent
|
||||
&:hover
|
||||
color white
|
||||
background rgba($color, .5)
|
||||
&:focus
|
||||
color white
|
||||
background rgba($color, .7)
|
||||
|
||||
.success
|
||||
$color = $success
|
||||
color white
|
||||
background $color
|
||||
&:hover
|
||||
background lighten($color, 30%)
|
||||
&:focus
|
||||
background lighten($color, 15%)
|
||||
&.outline
|
||||
color black
|
||||
border 2px solid $color
|
||||
background transparent
|
||||
&:hover
|
||||
color white
|
||||
background rgba($color, .5)
|
||||
&:focus
|
||||
color white
|
||||
background rgba($color, .7)
|
||||
|
||||
.danger
|
||||
$color = $danger
|
||||
color white
|
||||
background $color
|
||||
&:hover
|
||||
background lighten($color, 30%)
|
||||
&:focus
|
||||
background lighten($color, 15%)
|
||||
&.outline
|
||||
color black
|
||||
border 2px solid $color
|
||||
background transparent
|
||||
&:hover
|
||||
color white
|
||||
background rgba($color, .5)
|
||||
&:focus
|
||||
color white
|
||||
background rgba($color, .7)
|
||||
|
||||
.warning
|
||||
$color = $warning
|
||||
color white
|
||||
background $color
|
||||
&:hover
|
||||
background lighten($color, 30%)
|
||||
&:focus
|
||||
background lighten($color, 15%)
|
||||
&.outline
|
||||
color black
|
||||
border 2px solid $color
|
||||
background transparent
|
||||
&:hover
|
||||
color white
|
||||
background rgba($color, .5)
|
||||
&:focus
|
||||
color white
|
||||
background rgba($color, .7)
|
33
src/client/components/dzeio/Tag/index.tsx
Normal file
33
src/client/components/dzeio/Tag/index.tsx
Normal file
@ -0,0 +1,33 @@
|
||||
import React from 'react'
|
||||
|
||||
import { ColorType } from '../interfaces'
|
||||
import { buildClassName } from '../Util'
|
||||
import Link from '../Link'
|
||||
|
||||
import css from './Tag.module.styl'
|
||||
|
||||
interface Props {
|
||||
text: string
|
||||
color?: ColorType
|
||||
href: string
|
||||
as?: string
|
||||
outline?: boolean
|
||||
}
|
||||
|
||||
export default class Tag extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<Link
|
||||
href={this.props.href}
|
||||
as={this.props.as}
|
||||
className={buildClassName(
|
||||
css.tag,
|
||||
[css[this.props.color as string], this.props.color],
|
||||
[css.outline, this.props.outline]
|
||||
)}
|
||||
>
|
||||
{this.props.text}
|
||||
</Link>
|
||||
)
|
||||
|
||||
}
|
36
src/client/components/dzeio/Util.ts
Normal file
36
src/client/components/dzeio/Util.ts
Normal file
@ -0,0 +1,36 @@
|
||||
export function buildClassName(...classes: Array<Array<string | boolean | undefined> | string | undefined>): string | undefined {
|
||||
const classesFinal: Array<string> = []
|
||||
root: for (const classe of classes) {
|
||||
if (typeof classe === 'undefined') {
|
||||
continue
|
||||
}
|
||||
if (typeof classe === 'string') {
|
||||
classesFinal.push(classe)
|
||||
continue
|
||||
}
|
||||
const classToPut = classe.shift()
|
||||
if (typeof classToPut === 'undefined') {
|
||||
continue
|
||||
}
|
||||
for (const iterator of classe) {
|
||||
if (!iterator) {
|
||||
continue root
|
||||
}
|
||||
}
|
||||
classesFinal.push(classToPut + '')
|
||||
}
|
||||
if (classesFinal.length === 0) {
|
||||
return undefined
|
||||
}
|
||||
return classesFinal.join(' ')
|
||||
}
|
||||
|
||||
export const colors = {
|
||||
default: '#3949AB', // This color should never appear
|
||||
primary: '#3949AB',
|
||||
secondary: '#FCFCFC',
|
||||
info: '#03A9F4',
|
||||
success: '#2DCE89',
|
||||
danger: '#F5365C',
|
||||
warning: '#FB6340'
|
||||
}
|
24
src/client/components/dzeio/config.styl
Normal file
24
src/client/components/dzeio/config.styl
Normal file
@ -0,0 +1,24 @@
|
||||
$default = #3700B3 // This color should never appear
|
||||
$primary = #3700B3
|
||||
$secondary = #FFF
|
||||
$info = #0000FF
|
||||
$success = #00FF00
|
||||
$danger = #FF0000
|
||||
$warning = #FFFF00
|
||||
|
||||
$transitionTime = .15s
|
||||
$transitionFunction = ease-in-out
|
||||
$transition = $transitionTime $transitionFunction
|
||||
|
||||
$mobile = 768px
|
||||
$tablet = 1200px
|
||||
|
||||
$totalGapSize = 10%
|
||||
$colCount = 12
|
||||
$colCountTablet = 8
|
||||
$colCountMobile = 4
|
||||
|
||||
$gapSize = 16px //$totalGapSize / ($colCount+1)
|
||||
|
||||
rem($a)
|
||||
($a / 16)rem
|
13
src/client/components/dzeio/general.styl
Normal file
13
src/client/components/dzeio/general.styl
Normal file
@ -0,0 +1,13 @@
|
||||
*
|
||||
*::before
|
||||
*::after
|
||||
box-sizing border-box
|
||||
|
||||
html
|
||||
body
|
||||
body > div
|
||||
margin 0
|
||||
height 100%
|
||||
a
|
||||
color inherit
|
||||
text-decoration none
|
8
src/client/components/dzeio/interfaces.ts
Normal file
8
src/client/components/dzeio/interfaces.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { SVGAttributes } from 'react'
|
||||
|
||||
export type ColorType = 'primary' | 'secondary' | 'info' | 'success' | 'danger' | 'warning'
|
||||
|
||||
export interface IconProps extends SVGAttributes<SVGElement> {
|
||||
color?: string
|
||||
size?: string | number
|
||||
}
|
@ -1,2 +1,14 @@
|
||||
h1
|
||||
font-weight 600
|
||||
// General Styling
|
||||
|
||||
html
|
||||
body
|
||||
margin 0
|
||||
|
||||
a
|
||||
color inherit
|
||||
text-decoration none
|
||||
|
||||
*
|
||||
*::before
|
||||
*::after
|
||||
box-sizing border-box
|
||||
|
0
src/client/styl/pages/index.module.styl
Normal file
0
src/client/styl/pages/index.module.styl
Normal file
Reference in New Issue
Block a user