mirror of
https://github.com/dzeiocom/components.git
synced 2025-04-22 02:42:12 +00:00
0.2.0
Signed-off-by: Florian BOUILLON <florian.bouillon@delta-wings.net>
This commit is contained in:
parent
2013f0bf41
commit
d80fda2589
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
* text=lf
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
module/
|
||||
storybook-static/
|
||||
index.js
|
||||
*.js
|
||||
style.css
|
||||
yarn-error.log
|
||||
node_modules
|
||||
types
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@dzeio/components",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"license": "MIT",
|
||||
"main": "./index.js",
|
||||
"module": "./module/index.js",
|
||||
@ -44,7 +44,7 @@
|
||||
"scripts": {
|
||||
"storybook": "start-storybook -p 6006",
|
||||
"build-storybook": "build-storybook",
|
||||
"build": "tsc || rollup --config",
|
||||
"build": "tsc && rollup --config",
|
||||
"prepublishOnly": "yarn build"
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ interface Props {
|
||||
// Wrapper
|
||||
outline?: boolean
|
||||
className?: string
|
||||
onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => void
|
||||
|
||||
// Header
|
||||
title?: string
|
||||
@ -25,7 +26,7 @@ interface Props {
|
||||
|
||||
export default class Box extends React.Component<Props> {
|
||||
public render = () => (
|
||||
<BoxWrapper outline={this.props.outline} className={this.props.className}>
|
||||
<BoxWrapper onClick={this.props.onClick} outline={this.props.outline} className={this.props.className}>
|
||||
{(this.props.headerButtons || this.props.title || this.props.titleColSize || this.props.subtitle || this.props.delimiter || this.props.titleClassName) && (
|
||||
<BoxHeader
|
||||
title={this.props.title}
|
||||
@ -37,7 +38,6 @@ export default class Box extends React.Component<Props> {
|
||||
{this.props.headerButtons}
|
||||
</BoxHeader>
|
||||
)}
|
||||
<BoxHeader></BoxHeader>
|
||||
<BoxBody noPadding={this.props.noPadding}>
|
||||
{this.props.children}
|
||||
</BoxBody>
|
||||
|
@ -15,8 +15,8 @@
|
||||
border-radius 4px
|
||||
border none
|
||||
justify-content center
|
||||
color white
|
||||
background-color $default
|
||||
color $textOnMain
|
||||
background-color $main
|
||||
|
||||
// Chrome Specific
|
||||
outline none
|
||||
@ -68,22 +68,31 @@
|
||||
margin-top 8px
|
||||
|
||||
&:disabled
|
||||
background #E0E0E0 !important
|
||||
color #B0B0B0 !important
|
||||
transform none !important
|
||||
box-shadow none !important
|
||||
background $grayLight
|
||||
color $grayDark
|
||||
transform none
|
||||
box-shadow none
|
||||
cursor initial
|
||||
|
||||
&.outline
|
||||
border 2px solid @grayDark
|
||||
background transparent
|
||||
color @grayDark
|
||||
|
||||
@media (prefers-color-scheme dark)
|
||||
border 2px solid @grayLight
|
||||
color @grayLight
|
||||
|
||||
&.loading
|
||||
color transparent !important
|
||||
color transparent
|
||||
position relative
|
||||
pointer-events none
|
||||
|
||||
&::after
|
||||
content ""
|
||||
display block
|
||||
border white 2px solid
|
||||
border-color transparent transparent white white
|
||||
border $textOnMain 2px solid
|
||||
border-color transparent transparent $textOnMain $textOnMain
|
||||
width 1em
|
||||
position absolute
|
||||
top calc(50% - (1em / 2))
|
||||
@ -93,105 +102,69 @@
|
||||
box-sizing inherit
|
||||
animation ButtonLoading 1s infinite linear
|
||||
|
||||
|
||||
|
||||
.textInner
|
||||
margin-left 8px
|
||||
|
||||
.primary
|
||||
background-color $primary
|
||||
/**
|
||||
* $color: the color to use
|
||||
* $theme: the theme used ('lighten' | 'darken')
|
||||
*/
|
||||
btn($color, $theme)
|
||||
background-color $color
|
||||
|
||||
// Get Text Color
|
||||
$textColor = white
|
||||
if $theme is 'darken'
|
||||
$textColor = black
|
||||
else
|
||||
$textColor = white
|
||||
|
||||
color $textColor
|
||||
|
||||
&.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
|
||||
box-shadow 0 4px 4px rgba(@background-color,.2)
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
if $theme is 'darken'
|
||||
background-color darken(@background-color, 30%)
|
||||
else
|
||||
background-color lighten(@background-color, 30%)
|
||||
|
||||
&.loading::after
|
||||
border-color transparent transparent @color @color
|
||||
.info
|
||||
background-color $info
|
||||
&.outline
|
||||
color @background-color
|
||||
border-color @background-color
|
||||
&.loading
|
||||
color transparent
|
||||
&::after
|
||||
border-color transparent transparent $textColor $textColor
|
||||
|
||||
&:hover
|
||||
background-color @background-color
|
||||
.info:not(:disabled)
|
||||
btn($infoLight, 'darken')
|
||||
@media (prefers-color-scheme dark)
|
||||
btn($infoDark, 'lighten')
|
||||
|
||||
&:active
|
||||
&:focus
|
||||
background-color darken(@background-color, 30%)
|
||||
.success:not(:disabled)
|
||||
btn($successLight, 'darken')
|
||||
@media (prefers-color-scheme dark)
|
||||
btn($successDark, 'lighten')
|
||||
|
||||
&.loading::after
|
||||
border-color transparent transparent @background-color @background-color
|
||||
.success
|
||||
background-color $success
|
||||
&.outline
|
||||
color @background-color
|
||||
border-color @background-color
|
||||
.error:not(:disabled)
|
||||
btn($errorLight, 'darken')
|
||||
@media (prefers-color-scheme dark)
|
||||
btn($errorDark, 'lighten')
|
||||
|
||||
&: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
|
||||
.warning:not(:disabled)
|
||||
btn($warningLight, 'darken')
|
||||
@media (prefers-color-scheme dark)
|
||||
btn($warningDark, 'lighten')
|
||||
|
||||
@keyframes ButtonLoading
|
||||
0%
|
||||
|
@ -6,6 +6,8 @@ import Image from '../Image'
|
||||
|
||||
import css from './Button.module.styl'
|
||||
|
||||
// MAKE OUTLINE use Fieldset instead of the current one xd
|
||||
|
||||
interface Props {
|
||||
outline?: boolean
|
||||
nomargintop?: boolean
|
||||
@ -31,7 +33,7 @@ export default class Button extends React.Component<Props> {
|
||||
inner = (
|
||||
<>
|
||||
{typeof Icon === 'string' ? (
|
||||
<Image src={Icon} max={{ height: 16, width: 16 }} />
|
||||
<Image src={Icon} width={16} height={16} />
|
||||
) : (
|
||||
<Icon size={16} />
|
||||
)}
|
||||
|
@ -17,7 +17,6 @@ interface Props extends React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLIn
|
||||
|
||||
export default class Checkbox extends React.Component<Props> {
|
||||
|
||||
|
||||
public render() {
|
||||
const props: Props = Object.assign({}, this.props)
|
||||
delete props.label
|
||||
|
@ -1,7 +1,7 @@
|
||||
@import '../config.styl'
|
||||
|
||||
.fieldset
|
||||
border-radius 8px
|
||||
border-radius 4px
|
||||
border 2px solid grey
|
||||
transition all $transition
|
||||
margin 0
|
||||
@ -10,9 +10,10 @@
|
||||
font-weight 600
|
||||
transition all $transition
|
||||
padding 0 4px
|
||||
|
||||
@media (prefers-color-scheme dark)
|
||||
color white
|
||||
&:hover
|
||||
border-color black
|
||||
|
||||
> legend
|
||||
color $default
|
||||
@media (prefers-color-scheme dark)
|
||||
border-color white
|
||||
|
@ -5,61 +5,21 @@ import NextImage from 'next/image'
|
||||
import css from './Image.module.styl'
|
||||
|
||||
export interface ImageProps {
|
||||
defaultHeight?: number
|
||||
src?: string
|
||||
sources?: Array<string>
|
||||
src: string
|
||||
deleteOnError?: boolean
|
||||
downgradeOnError?: string
|
||||
canFullscreen?: boolean
|
||||
max?: {
|
||||
height?: number|string
|
||||
width?: number|string
|
||||
}
|
||||
width?: number|string
|
||||
default?: {
|
||||
height?: number|string
|
||||
width?: number|string
|
||||
}
|
||||
width: number
|
||||
height: number
|
||||
alt?: string
|
||||
classes?: string
|
||||
|
||||
// ClassNames
|
||||
parentClassName?: string
|
||||
className?: string
|
||||
|
||||
// Events
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
enum images {
|
||||
JPEG = 'image/jpeg',
|
||||
XICON = 'image/x-icon',
|
||||
TIFF = 'image/tiff'
|
||||
}
|
||||
|
||||
const mimeTypes = {
|
||||
apng: 'image/apng',
|
||||
bmp: 'image/bmp',
|
||||
gif: 'image/gif',
|
||||
|
||||
ico: images.XICON,
|
||||
cur: images.XICON,
|
||||
|
||||
jpg: images.JPEG,
|
||||
jpeg: images.JPEG,
|
||||
jfif: images.JPEG,
|
||||
pjpeg: images.JPEG,
|
||||
pjp: images.JPEG,
|
||||
|
||||
png: 'image/png',
|
||||
svg: 'image/svg+xml',
|
||||
|
||||
tif: images.TIFF,
|
||||
tiff: images.TIFF,
|
||||
|
||||
webp: 'image/webp'
|
||||
}
|
||||
|
||||
const getMimeType = (img: string) => {
|
||||
const arr = img.split('.')
|
||||
return mimeTypes[arr[arr.length-1] as 'apng'] || mimeTypes.png
|
||||
}
|
||||
|
||||
type evType<T = HTMLImageElement> = React.SyntheticEvent<T, Event>
|
||||
|
||||
export default class Image extends React.Component<ImageProps> {
|
||||
@ -69,7 +29,6 @@ export default class Image extends React.Component<ImageProps> {
|
||||
private parent: React.RefObject<HTMLDivElement> = React.createRef()
|
||||
private pic: React.RefObject<HTMLDivElement> = React.createRef()
|
||||
|
||||
private wasDowngraded = false
|
||||
private cardPos: Array<number> = []
|
||||
private cardSize: Array<number> = []
|
||||
|
||||
@ -104,30 +63,15 @@ export default class Image extends React.Component<ImageProps> {
|
||||
|
||||
public render() {
|
||||
const pic = (
|
||||
// <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
|
||||
// />
|
||||
// </picture>
|
||||
<div ref={this.pic} className={buildClassName(this.props.classes, css.parent)}>
|
||||
<div ref={this.pic} className={buildClassName(this.props.parentClassName, css.parent)}>
|
||||
<NextImage
|
||||
className={buildClassName([css.image], [this.props.className])}
|
||||
// ref={this.ref}
|
||||
src={this.props.src || ''}
|
||||
onClick={this.props.canFullscreen && this.onClick || this.props.onClick}
|
||||
onLoad={this.props.default && this.onLoad || undefined}
|
||||
src={this.props.src}
|
||||
onClick={this.props.canFullscreen ? this.onClick : this.props.onClick}
|
||||
onError={this.props.deleteOnError && this.onError || undefined}
|
||||
// layout="fill"
|
||||
width={200}
|
||||
height={44}
|
||||
// style={{
|
||||
// width: this.props.default?.width,
|
||||
// height: this.props.default?.height,
|
||||
// maxHeight: this.props.max?.height,
|
||||
// maxWidth: this.props.max?.width
|
||||
// }}
|
||||
width={this.props.width}
|
||||
height={this.props.height}
|
||||
alt={this.props.alt}
|
||||
/>
|
||||
</div>
|
||||
@ -191,8 +135,8 @@ export default class Image extends React.Component<ImageProps> {
|
||||
return
|
||||
}
|
||||
const w = this.valToPixel(this.props.width)
|
||||
const mh = this.valToPixel(this.props.max?.height)
|
||||
const mw = this.valToPixel(this.props.max?.width)
|
||||
const mh = this.valToPixel(this.props?.height)
|
||||
const mw = this.valToPixel(this.props?.width)
|
||||
c.classList.add(css.none)
|
||||
i.style.height = ''
|
||||
i.style.width = w
|
||||
|
@ -2,7 +2,12 @@
|
||||
|
||||
.parent
|
||||
position relative
|
||||
margin 16px
|
||||
margin 16px 0
|
||||
max-width 100%
|
||||
display inline-block
|
||||
|
||||
+ .parent
|
||||
margin-left 16px
|
||||
|
||||
label
|
||||
font-size 1rem
|
||||
@ -22,23 +27,104 @@
|
||||
svg
|
||||
position absolute
|
||||
color #AAA
|
||||
top 14px
|
||||
left 16px // input padding-left
|
||||
transition color $transition
|
||||
pointer-events none
|
||||
top 14px
|
||||
&.left
|
||||
left 16px // input padding-left
|
||||
|
||||
~ label
|
||||
left 16px + 24px + 16px
|
||||
|
||||
&.right
|
||||
right 16px
|
||||
|
||||
select
|
||||
appearance none
|
||||
|
||||
option
|
||||
background $foregroundLight
|
||||
color black
|
||||
@media (prefers-color-scheme dark)
|
||||
background lighten($foregroundDark, 5%)
|
||||
color white
|
||||
|
||||
textarea
|
||||
resize none
|
||||
overflow-y hidden
|
||||
|
||||
|
||||
/* Remove the arrows from the Number Input */
|
||||
input[type="number"]
|
||||
-moz-appearance textfield
|
||||
|
||||
input::-webkit-outer-spin-button
|
||||
input::-webkit-inner-spin-button
|
||||
-webkit-appearance none
|
||||
margin 0
|
||||
/* End */
|
||||
|
||||
.autocomplete
|
||||
display flex
|
||||
opacity 0
|
||||
transition all $transition
|
||||
pointer-events none
|
||||
// display flex
|
||||
flex-direction column
|
||||
list-style none
|
||||
position absolute
|
||||
top calc(100% - 4px)
|
||||
left 0
|
||||
width 100%
|
||||
z-index 100
|
||||
box-shadow 0 4px 8px rgba(black, .3)
|
||||
margin 0
|
||||
padding 0
|
||||
background darken($foregroundLight, 5%)
|
||||
@media (prefers-color-scheme dark)
|
||||
background lighten($foregroundDark, 5%)
|
||||
|
||||
border-bottom-left-radius 4px
|
||||
border-bottom-right-radius 4px
|
||||
max-height 25vh
|
||||
overflow-y auto
|
||||
@media (max-width $mobile)
|
||||
max-height 50vh
|
||||
&.reverse
|
||||
flex-direction column-reverse
|
||||
top initial
|
||||
bottom 100%
|
||||
box-shadow 0 -4px 8px rgba(black, .3)
|
||||
border-radius 0
|
||||
border-top-left-radius 4px
|
||||
border-top-right-radius 4px
|
||||
li
|
||||
transition all $transition
|
||||
padding 8px
|
||||
@media (max-width $mobile)
|
||||
padding 24px
|
||||
cursor pointer
|
||||
&:hover
|
||||
background darken(@background, 20%)
|
||||
@media (prefers-color-scheme dark)
|
||||
background lighten(lighten($foregroundDark, 5%), 20%)
|
||||
|
||||
|
||||
input:focus + .autocomplete
|
||||
select:focus + .autocomplete
|
||||
textarea:focus + .autocomplete
|
||||
.autocomplete:hover
|
||||
opacity 1
|
||||
pointer-events inherit
|
||||
|
||||
input
|
||||
select
|
||||
textarea
|
||||
padding 14px 16px
|
||||
height 56px
|
||||
border 2px solid rgba(black, .3)
|
||||
border-radius 4px
|
||||
max-width 100%
|
||||
box-sizing border-box
|
||||
font-size .875rem
|
||||
outline none
|
||||
@ -49,7 +135,7 @@
|
||||
border-color rgba(white, .3)
|
||||
color white
|
||||
|
||||
&:hover
|
||||
&:not(:disabled):hover
|
||||
border-color black
|
||||
@media (prefers-color-scheme dark)
|
||||
border-color white
|
||||
@ -72,6 +158,16 @@
|
||||
@media (prefers-color-scheme dark)
|
||||
background #202020
|
||||
|
||||
&:disabled
|
||||
border-color #999
|
||||
|
||||
@media (prefers-color-scheme dark)
|
||||
border-color #444
|
||||
~label
|
||||
color #444
|
||||
~ label
|
||||
color #999
|
||||
|
||||
&:invalid
|
||||
border-color $danger
|
||||
|
||||
@ -89,69 +185,20 @@
|
||||
~ 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
|
||||
&.iconLeft
|
||||
padding-left 16px + 24px + 16px
|
||||
|
||||
&.iconRight
|
||||
padding-right 16 + 24 + 16px
|
||||
&.filled
|
||||
border none
|
||||
background rgba(gray, .1)
|
||||
border-radius @border-radius @border-radius 0 0
|
||||
border-bottom 2px solid rgba(black,.4)
|
||||
|
||||
@media (prefers-color-scheme dark)
|
||||
background rgba(white, .1)
|
||||
border-bottom 2px solid rgba(white,.4)
|
||||
|
||||
&.opaque
|
||||
background white
|
||||
|
||||
@ -161,7 +208,8 @@
|
||||
&:hover
|
||||
background rgba(gray, .2)
|
||||
|
||||
|
||||
@media (prefers-color-scheme dark)
|
||||
background rgba(white, .2)
|
||||
|
||||
&.opaque
|
||||
background darken(white, 5%)
|
||||
@ -169,6 +217,7 @@
|
||||
background #1c1c1c
|
||||
&:focus
|
||||
background rgba(gray, .3)
|
||||
border-bottom 2px solid $default
|
||||
|
||||
&.opaque
|
||||
background white
|
||||
@ -185,14 +234,20 @@
|
||||
background transparent
|
||||
padding 0
|
||||
font-size .75rem
|
||||
~ svg ~ label
|
||||
~ svg.left ~ label
|
||||
left 16px + 24px + 16px // .input/padding-left label/padding-left
|
||||
~ svg.rotate
|
||||
transform rotateX(0)
|
||||
transition $transition
|
||||
|
||||
&:hover:focus ~ svg.rotate, ~.autocomplete:hover ~ svg.rotate
|
||||
transform rotateX(180deg)
|
||||
div
|
||||
display flex
|
||||
justify-content space-between
|
||||
padding 0 16px
|
||||
font-size .9em
|
||||
|
||||
&.block input
|
||||
&.block, &.block input, &.block select, &.block textarea
|
||||
width 100%
|
||||
display block
|
||||
|
@ -1,7 +1,8 @@
|
||||
import React, { FC } from 'react'
|
||||
|
||||
import { ChevronDown } from 'react-feather'
|
||||
import { IconProps, ColorType } from '../interfaces'
|
||||
import Text from '../Text'
|
||||
import { IconProps } from '../interfaces'
|
||||
import { buildClassName } from '../Util'
|
||||
import css from './Input.module.styl'
|
||||
|
||||
@ -9,34 +10,57 @@ interface Props extends React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLIn
|
||||
id?: string
|
||||
label?: string
|
||||
icon?: FC<IconProps>
|
||||
iconRight?: 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
|
||||
'range' | 'search' | 'tel' | 'time' | 'url' | 'week' |
|
||||
// Custom Types
|
||||
'select' | 'textarea'
|
||||
autocomplete?: Array<string>
|
||||
infinityText?: string
|
||||
filled?: boolean
|
||||
opaque?: boolean
|
||||
block?: boolean
|
||||
color?: ColorType
|
||||
children?: React.ReactNode
|
||||
}
|
||||
|
||||
export default class Input extends React.Component<Props> {
|
||||
interface States {
|
||||
charCount?: string
|
||||
textAreaHeight?: number
|
||||
value?: string
|
||||
isInFirstPartOfScreen?: boolean
|
||||
}
|
||||
|
||||
private charCountRef: React.RefObject<HTMLSpanElement> = React.createRef()
|
||||
export default class Input extends React.Component<Props, States> {
|
||||
|
||||
// any because f*ck types
|
||||
private inputRef: React.RefObject<any> = React.createRef()
|
||||
private parentRef: React.RefObject<HTMLDivElement> = React.createRef()
|
||||
|
||||
public componentDidMount() {
|
||||
this.updatecharCount()
|
||||
if (this.props.characterCount) {
|
||||
this.onChange()
|
||||
}
|
||||
if (this.props.type === 'textarea') {
|
||||
this.textareaHandler()
|
||||
}
|
||||
if (this.props.autocomplete) {
|
||||
window.addEventListener('scroll', this.parentScroll)
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
window.removeEventListener('scroll', this.parentScroll)
|
||||
}
|
||||
|
||||
public render() {
|
||||
const props: Props = Object.assign({}, this.props)
|
||||
const Icon = this.props.icon
|
||||
delete props.label
|
||||
delete props.children
|
||||
delete props.icon
|
||||
delete props.opaque
|
||||
delete props.helper
|
||||
@ -50,30 +74,30 @@ export default class Input extends React.Component<Props> {
|
||||
|
||||
const baseProps: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement> = {
|
||||
placeholder: this.props.placeholder || ' ',
|
||||
ref: this.props.inputRef,
|
||||
ref: this.props.inputRef || this.inputRef,
|
||||
className: buildClassName(
|
||||
[css.hasIcon, Icon],
|
||||
[css.iconLeft, this.props.icon],
|
||||
[css.iconRight, this.props.iconRight],
|
||||
[css.filled, this.props.filled],
|
||||
[css.opaque, this.props.opaque],
|
||||
[css[this.props.color as string], this.props.color]
|
||||
[css.opaque, this.props.opaque]
|
||||
),
|
||||
onInvalid: (ev: React.FormEvent<HTMLInputElement>) => ev.preventDefault()
|
||||
onInvalid: (ev: React.FormEvent<HTMLInputElement>) => ev.preventDefault(),
|
||||
}
|
||||
|
||||
let input: React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
|
||||
|
||||
if (this.props.type === 'number') {
|
||||
baseProps.type = 'text'
|
||||
baseProps.inputMode = 'numeric'
|
||||
baseProps.pattern = '[0-9]*'
|
||||
baseProps.onWheel = (ev: React.WheelEvent<HTMLInputElement>) => ev.currentTarget.blur()
|
||||
}
|
||||
|
||||
if (this.props.type === 'select') {
|
||||
input = (
|
||||
<select
|
||||
ref={this.props.selectRef}
|
||||
ref={this.props.selectRef || this.inputRef}
|
||||
{...this.props as React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLSelectElement>, HTMLSelectElement>}
|
||||
className={buildClassName(
|
||||
css.hasIcon,
|
||||
[css.iconLeft, this.props.icon],
|
||||
[css.iconRight, !this.props.disabled || this.props.iconRight],
|
||||
[css.filled, this.props.filled],
|
||||
[css[this.props.color as string], this.props.color]
|
||||
)}
|
||||
@ -81,6 +105,19 @@ export default class Input extends React.Component<Props> {
|
||||
{this.props.children}
|
||||
</select>
|
||||
)
|
||||
} else if (this.props.type === 'textarea') {
|
||||
delete baseProps.ref
|
||||
input = (
|
||||
<textarea
|
||||
{...props as React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>}
|
||||
{...baseProps as any}
|
||||
ref={this.inputRef}
|
||||
style={{minHeight: this.state?.textAreaHeight}}
|
||||
onKeyDown={this.textareaHandler}
|
||||
onKeyUp={this.textareaHandler}
|
||||
onFocus={this.textareaHandler}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
input = (
|
||||
<input
|
||||
@ -96,42 +133,94 @@ export default class Input extends React.Component<Props> {
|
||||
[css.parent],
|
||||
[css.block, this.props.block]
|
||||
)}
|
||||
onChangeCapture={this.props.characterCount ? this.updatecharCount : undefined}
|
||||
onChangeCapture={this.onChange}
|
||||
ref={this.parentRef}
|
||||
>
|
||||
{input}
|
||||
{this.props.type === 'select' && (
|
||||
<ChevronDown />
|
||||
|
||||
{this.props.autocomplete && this.props.autocomplete.indexOf(this.state?.value || '') === -1 && (
|
||||
<ul className={buildClassName(css.autocomplete, [css.reverse, !this.state?.isInFirstPartOfScreen])}>
|
||||
{this.props.autocomplete.filter((item) => item.includes(this.state?.value || '')).map((item) => (<li key={item} onClick={this.onAutoCompleteClick(item)}><Text>{item}</Text></li>))}
|
||||
</ul>
|
||||
)}
|
||||
{Icon && (
|
||||
<Icon />
|
||||
|
||||
{/* Process Icon */}
|
||||
{this.props.icon && (
|
||||
<this.props.icon className={css.left} />
|
||||
)}
|
||||
|
||||
{this.props.iconRight ? (
|
||||
<this.props.iconRight className={css.right} />
|
||||
) : ((this.props.type === 'select' || this.props.autocomplete) && !this.props.disabled) && (
|
||||
<ChevronDown className={buildClassName(css.right, css.rotate)} />
|
||||
)}
|
||||
|
||||
{/* Input Label */}
|
||||
{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>
|
||||
<Text type="span">{this.props.helper}</Text>
|
||||
{this.props.characterCount && (
|
||||
<Text type="span">{this.state?.charCount}</Text>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
private updatecharCount = async (event?: React.FormEvent<HTMLDivElement>) => {
|
||||
if (this.props.characterCount && this.charCountRef.current) {
|
||||
private parentScroll = async () => {
|
||||
const div = this.parentRef.current
|
||||
if (!div) {return}
|
||||
const result = !(div.offsetTop - window.scrollY >= window.innerHeight / 2)
|
||||
if (this.state.isInFirstPartOfScreen !== result) {
|
||||
this.setState({isInFirstPartOfScreen: result})
|
||||
}
|
||||
}
|
||||
|
||||
private getElement(): undefined | HTMLInputElement {
|
||||
const item = this.props.inputRef || this.props.selectRef || this.inputRef
|
||||
if (!item || !item.current) {return}
|
||||
return item.current
|
||||
}
|
||||
|
||||
private textareaHandler = async () =>
|
||||
this.setState({textAreaHeight: undefined}, () => {
|
||||
if (!this.inputRef.current) {return}
|
||||
this.setState({textAreaHeight: this.inputRef.current.scrollHeight})
|
||||
})
|
||||
|
||||
private onAutoCompleteClick = (value: string) => () => {
|
||||
console.log('test')
|
||||
const item = this.getElement()
|
||||
if (!item) {return}
|
||||
const valueSetter = Object.getOwnPropertyDescriptor(item, 'value')?.set
|
||||
const prototype = Object.getPrototypeOf(item)
|
||||
const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value')?.set
|
||||
if (valueSetter && valueSetter !== prototypeValueSetter) {
|
||||
// @ts-expect-error IDK why
|
||||
prototypeValueSetter.call(item, value)
|
||||
} else {
|
||||
// @ts-expect-error IDK why
|
||||
valueSetter.call(item, value)
|
||||
}
|
||||
item.dispatchEvent(new Event('input', {bubbles: true}))
|
||||
}
|
||||
|
||||
private onChange = async (event?: React.FormEvent<HTMLDivElement>) => {
|
||||
if (this.props.characterCount) {
|
||||
const max = this.props.maxLength || this.props.infinityText || 'Infinity'
|
||||
let currentCount = 0
|
||||
const baseItem = this.props.value || this.props.defaultValue || ''
|
||||
let currentCount = baseItem.toString().length
|
||||
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.setState({charCount: `${currentCount}/${max}`})
|
||||
}
|
||||
this.charCountRef.current.innerText = currentCount + ' / ' + max
|
||||
if (event) {
|
||||
this.setState({value: (event.target as HTMLInputElement).value })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,131 +1,48 @@
|
||||
import React from 'react'
|
||||
import { Bell, Grid } from 'react-feather'
|
||||
import Router from 'next/router'
|
||||
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 Menu from '../Menu'
|
||||
import css from './Navbar.module.styl'
|
||||
|
||||
interface States {
|
||||
domain?: string
|
||||
showUserMenu?: boolean
|
||||
}
|
||||
|
||||
interface Props {
|
||||
username?: string
|
||||
userPic?: string
|
||||
userMenu?: Array<{href: string, name: string}>
|
||||
loginUrl?: string
|
||||
registerUrl?: string
|
||||
logoUrl?: string
|
||||
logoLabel?: string
|
||||
logo?: {
|
||||
link?: string
|
||||
label?: string
|
||||
src: string
|
||||
alt: string
|
||||
alt?: string
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default class Navbar extends React.Component<Props, States> {
|
||||
|
||||
public state: States = {}
|
||||
|
||||
public constructor(props: Props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
|
||||
this.setState({
|
||||
domain: Router.query.domain as string
|
||||
})
|
||||
Router.events.on('routeChangeComplete', () => {
|
||||
this.setState({
|
||||
domain: Router.query.domain as string | undefined
|
||||
})
|
||||
})
|
||||
document.body.addEventListener('click', this.onClickAnywhere)
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
document.body.removeEventListener('click', this.onClickAnywhere)
|
||||
}
|
||||
export default class Navbar extends React.Component<Props> {
|
||||
|
||||
public render = () => (
|
||||
<nav className={buildClassName([css.navbar], [css.small, this.state.domain])}>
|
||||
<Row >
|
||||
<nav className={css.navbar}>
|
||||
<Row nomargin>
|
||||
{this.props.logo && (
|
||||
<Col>
|
||||
<Row align="center">
|
||||
<Link href={this.props.logoUrl || '/'}>
|
||||
<a aria-label={this.props.logoLabel || 'Homepage'}>
|
||||
<Link href={this.props.logo.link || '/'}>
|
||||
<a aria-label={this.props.logo.label || 'Homepage'}>
|
||||
<Image
|
||||
alt={this.props.logo.alt}
|
||||
src={this.props.logo.src}
|
||||
max={{ height: 70-32 }}
|
||||
height={38}
|
||||
width={120}
|
||||
/>
|
||||
</a>
|
||||
</Link>
|
||||
</Row>
|
||||
</Col>
|
||||
|
||||
)}
|
||||
|
||||
<Col>
|
||||
<Row justify="flex-end" align="center">
|
||||
{this.props.username ? (
|
||||
<>
|
||||
{/* <Bell className={css.icon} />
|
||||
<Grid className={css.icon} /> */}
|
||||
{this.props.userPic && (
|
||||
<Image
|
||||
onClick={this.onMenuClick}
|
||||
alt="User Profile Picture"
|
||||
classes={buildClassName([css.favicon], [css.userIcon])}
|
||||
src={this.props.userPic}
|
||||
/>
|
||||
)}
|
||||
<p
|
||||
onClick={this.props.userMenu ? this.onMenuClick : undefined}
|
||||
className={css.text}
|
||||
>
|
||||
{this.props.username}
|
||||
</p>
|
||||
{this.props.userMenu && (
|
||||
<Menu
|
||||
show={this.state.showUserMenu}
|
||||
pos={{ right: 16, top: 86 }}
|
||||
content={this.props.userMenu}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Button nomargintop href={this.props.loginUrl}>Login</Button>
|
||||
<Button nomargintop color="secondary" href={this.props.registerUrl}>Register</Button>
|
||||
</>
|
||||
)}
|
||||
{this.props.children}
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</nav>
|
||||
)
|
||||
|
||||
private onClickAnywhere = () => {
|
||||
this.setState({
|
||||
showUserMenu: false
|
||||
})
|
||||
}
|
||||
|
||||
private onMenuClick = () => {
|
||||
const newMenuState = !this.state.showUserMenu
|
||||
this.setState({
|
||||
showUserMenu: newMenuState
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
@import "../config.styl"
|
||||
|
||||
.popup
|
||||
position fixed
|
||||
height 100%
|
||||
@ -6,9 +8,21 @@
|
||||
left 0
|
||||
background rgba(black, .3)
|
||||
cursor pointer
|
||||
z-index 1000
|
||||
|
||||
.popupChild
|
||||
cursor initial
|
||||
z-index 1001
|
||||
|
||||
min-width 50%
|
||||
|
||||
@media (max-width $tablet)
|
||||
min-width 70%
|
||||
|
||||
@media (max-width $mobile)
|
||||
min-width 90%
|
||||
// min-height 50vh
|
||||
|
||||
.exit
|
||||
cursor pointer
|
||||
height 100%
|
||||
|
@ -1,8 +1,9 @@
|
||||
import React from 'react'
|
||||
import { X } from 'react-feather'
|
||||
import { BoxWrapper, BoxHeader, BoxBody } from '../Box'
|
||||
import { Props as HeaderProps } from '../Box/BoxHeader'
|
||||
import Text from '../Text'
|
||||
import Box from '../Box'
|
||||
import Row from '../Row'
|
||||
import { Props as HeaderProps } from '../Box/BoxHeader'
|
||||
|
||||
import css from './Popup.module.styl'
|
||||
|
||||
@ -15,20 +16,16 @@ interface Props {
|
||||
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>
|
||||
<Row nomargin onClick={this.parentClose} justify="center" align="center" className={css.popup}>
|
||||
<Box {...this.props.header} className={css.popupChild} onClick={(ev) => ev.stopPropagation()} headerButtons={(<Text><X onClick={this.props.onClose} className={css.exit} /></Text>)}>
|
||||
{this.props.children}
|
||||
</BoxBody>
|
||||
</BoxWrapper>
|
||||
</Box>
|
||||
</Row>
|
||||
)
|
||||
|
||||
private parentClose = (ev: React.MouseEvent<HTMLDivElement>) => {
|
||||
if ((ev.target as HTMLElement).classList.contains(css.popup) && this.props.onClose) {
|
||||
const target = ev.currentTarget
|
||||
if (target.classList.contains(css.popup) && this.props.onClose) {
|
||||
this.props.onClose()
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ export default class SidebarContainer extends React.Component<Props> {
|
||||
<nav className={css.sidebar}>
|
||||
<Link href="/dashboard">
|
||||
<a>
|
||||
<Image src="/assets/logo.svg" max={{ width: '100%' }} />
|
||||
<Image src="/assets/logo.svg" width={175} height={100} />
|
||||
</a>
|
||||
</Link>
|
||||
{this.menu.map((item, index) => (
|
||||
|
139
src/dzeio/Tag/Tag.module.styl
Normal file
139
src/dzeio/Tag/Tag.module.styl
Normal file
@ -0,0 +1,139 @@
|
||||
@import '../config'
|
||||
|
||||
.tag
|
||||
padding 8px 12px
|
||||
border-radius 8px
|
||||
margin-left 8px
|
||||
height 32px
|
||||
line-height 1
|
||||
display inline-block
|
||||
color white
|
||||
|
||||
background $default
|
||||
outline none
|
||||
&:hover
|
||||
background darken($default, 10%)
|
||||
&:focus
|
||||
background darken($default, 20%)
|
||||
|
||||
&.outline
|
||||
border 2px solid $default
|
||||
padding 6px 10px
|
||||
background transparent
|
||||
&:hover
|
||||
background rgba($default, .5)
|
||||
&:focus
|
||||
background rgba($default, .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)
|
17
src/dzeio/Tag/Tag.stories.tsx
Normal file
17
src/dzeio/Tag/Tag.stories.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { Meta } from '@storybook/react/types-6-0'
|
||||
import React from 'react'
|
||||
import Component from '.'
|
||||
|
||||
export default {
|
||||
title: 'DZEIO/Tag',
|
||||
component: Component
|
||||
} as Meta
|
||||
|
||||
export const Basic = (args: any) => {
|
||||
const content = args.content
|
||||
delete args.content
|
||||
|
||||
return (
|
||||
<Component {...args}>{content}</Component>
|
||||
)
|
||||
}
|
42
src/dzeio/Tag/index.tsx
Normal file
42
src/dzeio/Tag/index.tsx
Normal file
@ -0,0 +1,42 @@
|
||||
import React from 'react'
|
||||
|
||||
import { ColorType } from '../interfaces'
|
||||
import { buildClassName } from '../Util'
|
||||
import Link from '../Link'
|
||||
|
||||
import css from './Tag.module.styl'
|
||||
import Text from '../Text'
|
||||
|
||||
interface Props {
|
||||
text: string
|
||||
color?: ColorType
|
||||
href?: string
|
||||
outline?: boolean
|
||||
}
|
||||
|
||||
export default class Tag extends React.Component<Props> {
|
||||
|
||||
public render() {
|
||||
const classes = buildClassName(
|
||||
css.tag,
|
||||
[css[this.props.color as string], this.props.color],
|
||||
[css.outline, this.props.outline]
|
||||
)
|
||||
if (!this.props.href) {
|
||||
return (
|
||||
<Text
|
||||
className={classes}
|
||||
>{this.props.text}</Text>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Link
|
||||
href={this.props.href}
|
||||
className={classes}
|
||||
>
|
||||
{this.props.text}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -13,6 +13,8 @@
|
||||
.align-right
|
||||
text-align right
|
||||
|
||||
.align-left
|
||||
text-align left
|
||||
|
||||
@media (prefers-color-scheme dark)
|
||||
.white:not(.noDarkTheme)
|
||||
|
@ -3,10 +3,10 @@ import { buildClassName } from '../Util'
|
||||
import css from './Text.module.styl'
|
||||
interface Props {
|
||||
color?: 'black' | 'white'
|
||||
type?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'em'
|
||||
type?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'p' | 'em' | 'span'
|
||||
className?: string
|
||||
noDarkTheme?: boolean
|
||||
align?: 'right' | 'center'
|
||||
align?: 'left' | 'right' | 'center'
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ export default class Text extends React.Component<Props> {
|
||||
case 'h5': return (<h5 className={classes}>{this.props.children}</h5>)
|
||||
case 'h6': return (<h6 className={classes}>{this.props.children}</h6>)
|
||||
case 'em': return (<p className={classes}><em>{this.props.children}</em></p>)
|
||||
case 'span': return (<span className={classes}>{this.props.children}</span>)
|
||||
default: return (<p className={classes}>{this.props.children}</p>)
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,32 @@
|
||||
$default = #4285f4 // This color should never appear
|
||||
$primary = #4285f4
|
||||
$secondary = #FCFCFC
|
||||
$info = #03A9F4
|
||||
$success = #2DCE89
|
||||
$danger = #F5365C
|
||||
$warning = #FB6340
|
||||
|
||||
$main = #4285F4
|
||||
$textOnMain = white
|
||||
|
||||
$infoDark = #304FFE
|
||||
$infoLight = #29B6F6
|
||||
|
||||
$successDark = #388E3C
|
||||
$successLight = #4CAF50
|
||||
|
||||
$errorDark = #D32F2F
|
||||
$errorLight = #F44336
|
||||
|
||||
$warningDark = #F57C00
|
||||
$warningLight = #FF9800
|
||||
|
||||
$backgroundDark = #161616
|
||||
$backgroundLight = #EEEEEE
|
||||
$foregroundDark = #202020
|
||||
$foregroundLight = #FFFFFF
|
||||
|
||||
$grayDark = #B0B0B0
|
||||
$grayLight = #E0E0E0
|
||||
|
||||
|
||||
$transitionTime = .15s
|
||||
$transitionFunction = ease-in-out
|
||||
$transition = $transitionTime $transitionFunction
|
||||
|
||||
$darkBackground = #161616
|
||||
|
||||
// Breakpoints
|
||||
$mobile = 768px
|
||||
@ -22,7 +38,17 @@ $colCount = 12
|
||||
$colCountTablet = 8
|
||||
$colCountMobile = 4
|
||||
|
||||
$gapSize = 16px //$totalGapSize / ($colCount+1)
|
||||
$gapSize = 16px
|
||||
|
||||
rem($a)
|
||||
($a / 16)rem
|
||||
|
||||
// @deprecated colors
|
||||
$primary = $main
|
||||
$default = $main
|
||||
$secondary = $main
|
||||
$info = $infoLight
|
||||
$success = $successLight
|
||||
$danger = $errorLight
|
||||
$warning = $warningLight
|
||||
$darkBackground = $backgroundDark
|
||||
|
@ -1,11 +1,10 @@
|
||||
@import "_aileron"
|
||||
@import "config"
|
||||
|
||||
*
|
||||
*::before
|
||||
*::after
|
||||
box-sizing border-box
|
||||
|
||||
html
|
||||
font-family Aileron, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif
|
||||
|
||||
html
|
||||
@ -13,11 +12,36 @@ body
|
||||
body > div[id="__next"]
|
||||
margin 0
|
||||
min-height 100vh
|
||||
background #f5f5f5
|
||||
background $backgroundLight
|
||||
|
||||
@media (prefers-color-scheme dark)
|
||||
background #202020
|
||||
background $backgroundDark
|
||||
|
||||
a
|
||||
color inherit
|
||||
text-decoration none
|
||||
|
||||
/* width */
|
||||
::-webkit-scrollbar {
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
/* Track */
|
||||
::-webkit-scrollbar-track
|
||||
background $foregroundLight
|
||||
@media (prefers-color-scheme dark)
|
||||
background $foregroundDark
|
||||
|
||||
::-webkit-scrollbar-thumb
|
||||
background: darken($foregroundLight, 16%)
|
||||
@media (prefers-color-scheme dark)
|
||||
background lighten($foregroundDark, 16%)
|
||||
&:hover
|
||||
background: darken($foregroundLight, 24%)
|
||||
@media (prefers-color-scheme dark)
|
||||
background: lighten($foregroundDark, 24%)
|
||||
|
||||
&:active
|
||||
background: darken($foregroundLight, 32%)
|
||||
@media (prefers-color-scheme dark)
|
||||
background: lighten($foregroundDark, 32%)
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { SVGAttributes } from 'react'
|
||||
|
||||
export type ColorType = 'primary' | 'secondary' | 'info' | 'success' | 'danger' | 'warning'
|
||||
export type ColorType = 'primary' | 'info' | 'success' | 'error' | 'warning'
|
||||
|
||||
export interface IconProps extends SVGAttributes<SVGElement> {
|
||||
color?: string
|
||||
|
@ -1,11 +1,15 @@
|
||||
.fullscrean
|
||||
@import './config'
|
||||
|
||||
.fullscreen
|
||||
min-height 100vh
|
||||
|
||||
.fullHeight
|
||||
height 50vh
|
||||
.w100p
|
||||
width 100%
|
||||
|
||||
.hideMobile
|
||||
@media (max-width $mobile)
|
||||
display none
|
||||
|
||||
|
||||
// Utils for Width
|
||||
.w50p
|
||||
width 50%
|
||||
.hideTablet
|
||||
@media (max-width $tablet)
|
||||
display none
|
||||
|
@ -18,6 +18,7 @@ import Popup from './dzeio/Popup'
|
||||
import Row from './dzeio/Row'
|
||||
import SidebarContainer from './dzeio/SidebarContainer'
|
||||
import Table from './dzeio/Table'
|
||||
import Tag from './dzeio/Tag'
|
||||
import Text from './dzeio/Text'
|
||||
import * as Util from './dzeio/Util'
|
||||
|
||||
@ -47,6 +48,7 @@ export {
|
||||
Row,
|
||||
SidebarContainer,
|
||||
Table,
|
||||
Tag,
|
||||
Text,
|
||||
Util
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user