From d80fda2589e05d786855c1a864b5437f648e96de Mon Sep 17 00:00:00 2001 From: Florian BOUILLON Date: Tue, 23 Feb 2021 14:06:55 +0100 Subject: [PATCH] 0.2.0 Signed-off-by: Florian BOUILLON --- .gitattributes | 1 + .gitignore | 3 +- package.json | 4 +- src/dzeio/Box/index.tsx | 4 +- src/dzeio/Button/Button.module.styl | 155 ++++++++------------ src/dzeio/Button/index.tsx | 4 +- src/dzeio/Checkbox/index.tsx | 1 - src/dzeio/Fieldset/Fieldset.module.styl | 9 +- src/dzeio/Image/index.tsx | 86 ++--------- src/dzeio/Input/Input.module.styl | 185 +++++++++++++++--------- src/dzeio/Input/index.tsx | 159 +++++++++++++++----- src/dzeio/Navbar/index.tsx | 107 ++------------ src/dzeio/Popup/Popup.module.styl | 14 ++ src/dzeio/Popup/index.tsx | 21 ++- src/dzeio/SidebarContainer/index.tsx | 2 +- src/dzeio/Tag/Tag.module.styl | 139 ++++++++++++++++++ src/dzeio/Tag/Tag.stories.tsx | 17 +++ src/dzeio/Tag/index.tsx | 42 ++++++ src/dzeio/Text/Text.module.styl | 2 + src/dzeio/Text/index.tsx | 5 +- src/dzeio/config.styl | 44 ++++-- src/dzeio/general.styl | 32 +++- src/dzeio/interfaces.ts | 2 +- src/dzeio/util.styl | 18 ++- src/index.ts | 2 + 25 files changed, 654 insertions(+), 404 deletions(-) create mode 100644 .gitattributes create mode 100644 src/dzeio/Tag/Tag.module.styl create mode 100644 src/dzeio/Tag/Tag.stories.tsx create mode 100644 src/dzeio/Tag/index.tsx diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7d07d70 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=lf diff --git a/.gitignore b/.gitignore index f062cf5..ae90d97 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ module/ storybook-static/ -index.js +*.js style.css yarn-error.log node_modules +types \ No newline at end of file diff --git a/package.json b/package.json index cd7eca7..3bd553d 100644 --- a/package.json +++ b/package.json @@ -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" } } diff --git a/src/dzeio/Box/index.tsx b/src/dzeio/Box/index.tsx index 92b10af..4aff485 100644 --- a/src/dzeio/Box/index.tsx +++ b/src/dzeio/Box/index.tsx @@ -9,6 +9,7 @@ interface Props { // Wrapper outline?: boolean className?: string + onClick?: (event: React.MouseEvent) => void // Header title?: string @@ -25,7 +26,7 @@ interface Props { export default class Box extends React.Component { public render = () => ( - + {(this.props.headerButtons || this.props.title || this.props.titleColSize || this.props.subtitle || this.props.delimiter || this.props.titleClassName) && ( { {this.props.headerButtons} )} - {this.props.children} diff --git a/src/dzeio/Button/Button.module.styl b/src/dzeio/Button/Button.module.styl index ebecc56..7484105 100644 --- a/src/dzeio/Button/Button.module.styl +++ b/src/dzeio/Button/Button.module.styl @@ -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 - &.outline - color @background-color - border-color @background-color +/** + * $color: the color to use + * $theme: the theme used ('lighten' | 'darken') +*/ +btn($color, $theme) + background-color $color - &:hover - background-color @background-color + // Get Text Color + $textColor = white + if $theme is 'darken' + $textColor = black + else + $textColor = white - &: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 + 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 -.warning - background-color $warning - - &.outline - color @background-color - border-color @background-color + &:hover + &:active + &:focus + color @color &:hover background-color @background-color + box-shadow 0 4px 4px rgba(@background-color,.2) &:active &:focus - background-color darken(@background-color, 30%) + if $theme is 'darken' + background-color darken(@background-color, 30%) + else + background-color lighten(@background-color, 30%) - &.loading::after - border-color transparent transparent @background-color @background-color + &.loading + color transparent + &::after + border-color transparent transparent $textColor $textColor + +.info:not(:disabled) + btn($infoLight, 'darken') + @media (prefers-color-scheme dark) + btn($infoDark, 'lighten') + +.success:not(:disabled) + btn($successLight, 'darken') + @media (prefers-color-scheme dark) + btn($successDark, 'lighten') + +.error:not(:disabled) + btn($errorLight, 'darken') + @media (prefers-color-scheme dark) + btn($errorDark, 'lighten') + +.warning:not(:disabled) + btn($warningLight, 'darken') + @media (prefers-color-scheme dark) + btn($warningDark, 'lighten') @keyframes ButtonLoading 0% diff --git a/src/dzeio/Button/index.tsx b/src/dzeio/Button/index.tsx index 559ae95..60958c6 100644 --- a/src/dzeio/Button/index.tsx +++ b/src/dzeio/Button/index.tsx @@ -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 { inner = ( <> {typeof Icon === 'string' ? ( - + ) : ( )} diff --git a/src/dzeio/Checkbox/index.tsx b/src/dzeio/Checkbox/index.tsx index 172619a..78466b2 100644 --- a/src/dzeio/Checkbox/index.tsx +++ b/src/dzeio/Checkbox/index.tsx @@ -17,7 +17,6 @@ interface Props extends React.DetailedHTMLProps { - public render() { const props: Props = Object.assign({}, this.props) delete props.label diff --git a/src/dzeio/Fieldset/Fieldset.module.styl b/src/dzeio/Fieldset/Fieldset.module.styl index 9538ac0..159d938 100644 --- a/src/dzeio/Fieldset/Fieldset.module.styl +++ b/src/dzeio/Fieldset/Fieldset.module.styl @@ -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 diff --git a/src/dzeio/Image/index.tsx b/src/dzeio/Image/index.tsx index d56451f..32b9d97 100644 --- a/src/dzeio/Image/index.tsx +++ b/src/dzeio/Image/index.tsx @@ -5,61 +5,21 @@ import NextImage from 'next/image' import css from './Image.module.styl' export interface ImageProps { - defaultHeight?: number - src?: string - sources?: Array + 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 = React.SyntheticEvent export default class Image extends React.Component { @@ -69,7 +29,6 @@ export default class Image extends React.Component { private parent: React.RefObject = React.createRef() private pic: React.RefObject = React.createRef() - private wasDowngraded = false private cardPos: Array = [] private cardSize: Array = [] @@ -104,30 +63,15 @@ export default class Image extends React.Component { public render() { const pic = ( - // - // {this.props.sources && this.props.sources.map((el, index) => ( - // - // ))} - // - // -
+
@@ -191,8 +135,8 @@ export default class Image extends React.Component { 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 diff --git a/src/dzeio/Input/Input.module.styl b/src/dzeio/Input/Input.module.styl index 7cecd16..7b56d75 100644 --- a/src/dzeio/Input/Input.module.styl +++ b/src/dzeio/Input/Input.module.styl @@ -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 + ~ 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 diff --git a/src/dzeio/Input/index.tsx b/src/dzeio/Input/index.tsx index 19532b0..24cab51 100644 --- a/src/dzeio/Input/index.tsx +++ b/src/dzeio/Input/index.tsx @@ -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 + iconRight?: FC helper?: string characterCount?: boolean inputRef?: React.RefObject selectRef?: React.RefObject 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 infinityText?: string filled?: boolean opaque?: boolean block?: boolean - color?: ColorType children?: React.ReactNode } -export default class Input extends React.Component { +interface States { + charCount?: string + textAreaHeight?: number + value?: string + isInFirstPartOfScreen?: boolean +} - private charCountRef: React.RefObject = React.createRef() +export default class Input extends React.Component { + + // any because f*ck types + private inputRef: React.RefObject = React.createRef() + private parentRef: React.RefObject = 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 { const baseProps: React.DetailedHTMLProps, 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) => ev.preventDefault() + onInvalid: (ev: React.FormEvent) => ev.preventDefault(), } let input: React.DetailedHTMLProps, HTMLInputElement> if (this.props.type === 'number') { - baseProps.type = 'text' - baseProps.inputMode = 'numeric' - baseProps.pattern = '[0-9]*' + baseProps.onWheel = (ev: React.WheelEvent) => ev.currentTarget.blur() } if (this.props.type === 'select') { input = ( ) + } else if (this.props.type === 'textarea') { + delete baseProps.ref + input = ( +