Last active
July 17, 2022 12:19
-
-
Save bbg/5224d4e10034f3e7eb1f3be9f788cd32 to your computer and use it in GitHub Desktop.
generic-component-styled
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// <reference types="styled-jsx" /> | |
| import clsx from 'clsx'; | |
| import React, { Fragment } from 'react'; | |
| type Property = { | |
| display: | |
| | 'block' | |
| | 'inline-block' | |
| | 'inline' | |
| | 'flex' | |
| | 'inline-flex' | |
| | 'table' | |
| | 'inline-table' | |
| | 'table-caption' | |
| | 'table-cell' | |
| | 'table-column' | |
| | 'table-column-group' | |
| | 'table-footer-group' | |
| | 'table-header-group' | |
| | 'table-row-group' | |
| | 'table-row' | |
| | 'flow-root' | |
| | 'grid' | |
| | 'inline-grid' | |
| | 'contents' | |
| | 'list-item' | |
| | 'none'; | |
| flexDirection: 'row' | 'column' | 'row-reverse' | 'column-reverse' | string; | |
| flexWrap: 'wrap' | 'nowrap' | 'wrap-reverse' | string; | |
| flexBasis: number | string; | |
| flexGrow: '1' | '0' | string; | |
| flexShrink: '1' | '0' | string; | |
| justifyContent: | |
| | 'flex-start' | |
| | 'flex-end' | |
| | 'center' | |
| | 'space-between' | |
| | 'space-around' | |
| | string; | |
| alignItems: | |
| | 'flex-start' | |
| | 'flex-end' | |
| | 'center' | |
| | 'baseline' | |
| | 'stretch' | |
| | string; | |
| alignContent: | |
| | 'flex-start' | |
| | 'flex-end' | |
| | 'center' | |
| | 'space-between' | |
| | 'space-around' | |
| | 'stretch' | |
| | string; | |
| order: | |
| | '0' | |
| | '1' | |
| | '2' | |
| | '3' | |
| | '4' | |
| | '5' | |
| | '6' | |
| | '7' | |
| | '8' | |
| | '9' | |
| | '10' | |
| | '11' | |
| | '12' | |
| | '-9999' | |
| | '9999' | |
| | 'auto' | |
| | string; | |
| flex: | |
| | '1 1 0%' | |
| | '0 1 auto' | |
| | '1 1 auto' | |
| | 'initial' | |
| | 'inherit' | |
| | 'unset' | |
| | 'none' | |
| | string; | |
| alignSelf: | |
| | 'auto' | |
| | 'flex-start' | |
| | 'flex-end' | |
| | 'center' | |
| | 'baseline' | |
| | 'stretch' | |
| | string; | |
| justifySelf: | |
| | 'auto' | |
| | 'flex-start' | |
| | 'flex-end' | |
| | 'center' | |
| | 'space-between' | |
| | 'space-around' | |
| | string; | |
| shrink: number; | |
| placeContent: | |
| | 'center' | |
| | 'start' | |
| | 'end' | |
| | 'space-between' | |
| | 'space-around' | |
| | 'space-evenly' | |
| | 'stretch' | |
| | string; | |
| placeItems: 'center' | 'start' | 'end' | 'stretch' | string; | |
| placeSelf: 'center' | 'start' | 'end' | 'stretch' | 'auto' | string; | |
| gridTemplateColumns: string; | |
| gridColumn: string; | |
| gridColumnStart: | |
| | '1' | |
| | '2' | |
| | '3' | |
| | '4' | |
| | '5' | |
| | '6' | |
| | '7' | |
| | '8' | |
| | '9' | |
| | '10' | |
| | '11' | |
| | '12' | |
| | '13' | |
| | 'auto' | |
| | string; | |
| gridColumnEnd: | |
| | '1' | |
| | '2' | |
| | '3' | |
| | '4' | |
| | '5' | |
| | '6' | |
| | '7' | |
| | '8' | |
| | '9' | |
| | '10' | |
| | '11' | |
| | '12' | |
| | '13' | |
| | 'auto' | |
| | string; | |
| gridTemplateRows: 'none' | string; | |
| gridRow: string; | |
| gridRowStart: '1' | '2' | '3' | '4' | '5' | '6' | '7' | 'auto' | string; | |
| gridRowEnd: '1' | '2' | '3' | '4' | '5' | '6' | '7' | 'auto' | string; | |
| gridAutoFlow: | |
| | 'row' | |
| | 'column' | |
| | 'dense' | |
| | 'row dense' | |
| | 'column dense' | |
| | string; | |
| gridAutoColumns: | |
| | 'auto' | |
| | 'min-content' | |
| | 'max-content' | |
| | 'minmax(0, 1fr)' | |
| | string; | |
| gridAutoRows: | |
| | 'auto' | |
| | 'min-content' | |
| | 'max-content' | |
| | 'minmax(0, 1fr)' | |
| | string; | |
| p: number | string; | |
| m: number | string; | |
| w: number | string; | |
| h: number | string; | |
| minw: number | string; | |
| maxw: number | string; | |
| minh: number | string; | |
| maxh: number | string; | |
| ygap: number | string; | |
| xgap: number | string; | |
| radius: number | string; | |
| lineHeight: number | string; | |
| color: string; | |
| bgColor: string; | |
| fontSize: string; | |
| fontWeight: 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900; | |
| textAlign: 'left' | 'right' | 'center' | 'justify' | string; | |
| textColor: string; | |
| textDecoration: | |
| | 'underline' | |
| | 'line-through' | |
| | 'none' | |
| | 'overline' | |
| | 'no-underline' | |
| | string; | |
| textDecorationColor: string; | |
| textDecorationStyle: | |
| | 'solid' | |
| | 'double' | |
| | 'dotted' | |
| | 'dashed' | |
| | 'wavy' | |
| | string; | |
| textDecorationThickness: number | string; | |
| textUnderlineOffset: number | string; | |
| textTransform: string; | |
| textOverflow: string; | |
| textIndent: number | string; | |
| border: string; | |
| borderWidth: number; | |
| borderStyle: string; | |
| borderColor: string; | |
| borderTop: string; | |
| borderRight: string; | |
| borderBottom: string; | |
| borderLeft: string; | |
| borderTopLeftRadius: string; | |
| borderTopRightRadius: string; | |
| borderBottomLeftRadius: string; | |
| borderBottomRightRadius: string; | |
| borderImage: string; | |
| borderImageSlice: string; | |
| borderImageWidth: string; | |
| borderImageOutset: string; | |
| borderCollapse: 'separate' | 'collapse' | string; | |
| borderSpacing: number | string; | |
| tableLayout: 'auto' | 'fixed' | string; | |
| outline: string; | |
| outlineWidth: number | string; | |
| outlineColor: string; | |
| outlineStyle: | |
| | 'solid' | |
| | 'double' | |
| | 'dotted' | |
| | 'dashed' | |
| | 'wavy' | |
| | 'hidden' | |
| | string; | |
| outlineOffset: number | string; | |
| outlineRadius: number | string; | |
| backgroundAttachment: 'fixed' | 'scroll' | 'local' | string; | |
| backgroundClip: | |
| | 'border-box' | |
| | 'padding-box' | |
| | 'content-box' | |
| | 'text' | |
| | string; | |
| backgroundColor: string; | |
| backgroundOrigin: 'border-box' | 'padding-box' | 'content-box' | string; | |
| backgroundPosition: | |
| | 'left' | |
| | 'center' | |
| | 'right' | |
| | 'bottom' | |
| | 'center' | |
| | 'left bottom' | |
| | 'left top' | |
| | 'right bottom' | |
| | 'right top' | |
| | 'top' | |
| | string; | |
| backgroundRepeat: | |
| | 'repeat' | |
| | 'repeat-x' | |
| | 'repeat-y' | |
| | 'no-repeat' | |
| | 'round' | |
| | 'space' | |
| | string; | |
| backgroundSize: 'auto' | 'cover' | 'contain' | string; | |
| backgroundImage: string; | |
| boxShadow: string; | |
| opacity: number | string; | |
| zIndex: number | string; | |
| mixBlendMode: | |
| | 'normal' | |
| | 'multiply' | |
| | 'screen' | |
| | 'overlay' | |
| | 'darken' | |
| | 'lighten' | |
| | 'color-dodge' | |
| | 'color-burn' | |
| | 'hard-light' | |
| | 'soft-light' | |
| | 'difference' | |
| | 'exclusion' | |
| | 'hue' | |
| | 'saturation' | |
| | 'color' | |
| | 'luminosity' | |
| | 'normal' | |
| | 'inherit' | |
| | 'plus-lighter' | |
| | string; | |
| backgroundBlendMode: | |
| | 'multiply' | |
| | 'screen' | |
| | 'overlay' | |
| | 'darken' | |
| | 'lighten' | |
| | 'color-dodge' | |
| | 'color-burn' | |
| | 'hard-light' | |
| | 'soft-light' | |
| | 'difference' | |
| | 'exclusion' | |
| | 'hue' | |
| | 'saturation' | |
| | 'color' | |
| | 'luminosity' | |
| | 'normal' | |
| | 'inherit' | |
| | string; | |
| filter: string; | |
| backdropFilter: string; | |
| transform: string; | |
| transformOrigin: string; | |
| transition: string; | |
| transitionProperty: string; | |
| transitionDuration: string; | |
| transitionTimingFunction: string; | |
| transitionDelay: string; | |
| accentColor: string; | |
| appearance: 'none'; | |
| cursor: 'auto' | 'default' | 'pointer' | 'text' | 'wait' | string; | |
| caretColor: string; | |
| pointerEvents: 'auto' | 'none' | 'all' | string; | |
| resize: 'none' | 'both' | 'horizontal' | 'vertical' | string; | |
| float: 'left' | 'right' | 'none' | string; | |
| clear: 'left' | 'right' | 'both' | 'none' | string; | |
| isolation: 'isolate' | 'auto' | 'inherit' | 'unset' | string; | |
| objectFit: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' | string; | |
| objectPosition: | |
| | 'bottom' | |
| | 'center' | |
| | 'left' | |
| | 'left bottom' | |
| | 'left top' | |
| | 'right' | |
| | 'right bottom' | |
| | 'right top' | |
| | 'top' | |
| | string; | |
| overflow: 'auto' | 'hidden' | 'clip' | 'auto' | 'visible' | 'scroll' | string; | |
| overflowX: | |
| | 'auto' | |
| | 'hidden' | |
| | 'clip' | |
| | 'auto' | |
| | 'visible' | |
| | 'scroll' | |
| | string; | |
| overflowY: | |
| | 'auto' | |
| | 'hidden' | |
| | 'clip' | |
| | 'auto' | |
| | 'visible' | |
| | 'scroll' | |
| | string; | |
| overscroll: 'auto' | 'contain' | 'none' | string; | |
| overscrollX: 'auto' | 'contain' | 'none' | string; | |
| overscrollY: 'auto' | 'contain' | 'none' | string; | |
| verticalAlign: | |
| | 'baseline' | |
| | 'top' | |
| | 'middle' | |
| | 'bottom' | |
| | 'text-top' | |
| | 'text-bottom' | |
| | 'sub' | |
| | 'super' | |
| | string; | |
| whiteSpace: 'normal' | 'nowrap' | 'pre' | 'pre-line' | 'pre-wrap' | string; | |
| wordWrap: string; | |
| content: 'none'; | |
| scrollBehavior: 'auto' | 'smooth'; | |
| scrollMargin: number | string; | |
| scrollMarginLeft: number | string; | |
| scrollMarginRight: number | string; | |
| scrollMarginTop: number | string; | |
| scrollMarginBottom: number | string; | |
| scrollPadding: number | string; | |
| scrollPaddingLeft: number | string; | |
| scrollPaddingRight: number | string; | |
| scrollPaddingTop: number | string; | |
| scrollPaddingBottom: number | string; | |
| scrollSnapAlign: 'none' | 'start' | 'center' | 'end' | 'stretch'; | |
| scrollSnapStop: 'always' | 'normal' | 'never'; | |
| scrollSnapType: 'none' | 'mandatory' | 'proximity' | string; | |
| touchAction: | |
| | 'auto' | |
| | 'none' | |
| | 'pan-x' | |
| | 'pan-left;' | |
| | 'pan-right;' | |
| | 'pan-y' | |
| | 'pan-up' | |
| | 'pan-down' | |
| | 'pinch-zoom' | |
| | 'manipulation'; | |
| userSelect: 'none' | 'text' | 'all' | 'auto' | string; | |
| willChange: 'auto' | 'scroll-position' | 'contents' | 'transform' | string; | |
| fill: string; | |
| stroke: string; | |
| strokeWidth: number | string; | |
| aspectRatio: 'auto' | '1 / 1' | '16 / 9' | number | string; | |
| columns: number | string; | |
| breakAfter: | |
| | 'auto' | |
| | 'avoid' | |
| | 'all' | |
| | 'avoid-page' | |
| | 'page' | |
| | 'left' | |
| | 'right' | |
| | 'column' | |
| | string; | |
| breakBefore: | |
| | 'auto' | |
| | 'avoid' | |
| | 'all' | |
| | 'avoid-page' | |
| | 'page' | |
| | 'left' | |
| | 'right' | |
| | 'column' | |
| | string; | |
| breakInside: 'auto' | 'avoid' | 'avoid-page' | 'avoid-column' | string; | |
| boxDecorationBreak: 'slice' | 'clone' | string; | |
| boxSizing: 'border-box' | 'content-box' | string; | |
| position: 'static' | 'relative' | 'absolute' | 'fixed' | 'sticky' | string; | |
| top: number | string; | |
| left: number | string; | |
| bottom: number | string; | |
| right: number | string; | |
| visibility: 'visible' | 'hidden' | 'collapse' | string; | |
| hover: Record<string, string>; | |
| /* hover?: { | |
| [property: string]: Property; | |
| }; */ | |
| }; | |
| type GenericOwnProps<E extends React.ElementType = React.ElementType> = Partial< | |
| Property | |
| > & { | |
| children?: JSX.Element | JSX.Element[] | string; | |
| as?: E; | |
| cls?: string | Record<string, string> | string[]; | |
| }; | |
| export type GenericProps<E extends React.ElementType> = GenericOwnProps<E> & | |
| Omit<React.ComponentProps<E>, keyof GenericOwnProps>; | |
| const __DEFAULT_ELEMENT__ = 'div'; | |
| const shortName = [ | |
| { | |
| shortname: 'p', | |
| longname: 'padding', | |
| }, | |
| { | |
| shortname: 'm', | |
| longname: 'margin', | |
| }, | |
| { | |
| shortname: 'w', | |
| longname: 'width', | |
| }, | |
| { | |
| shortname: 'h', | |
| longname: 'height', | |
| }, | |
| { | |
| shortname: 'minw', | |
| longname: 'minWidth', | |
| }, | |
| { | |
| shortname: 'maxw', | |
| longname: 'maxWidth', | |
| }, | |
| { | |
| shortname: 'minh', | |
| longname: 'minHeight', | |
| }, | |
| { | |
| shortname: 'maxh', | |
| longname: 'maxHeight', | |
| }, | |
| { | |
| shortname: 'ygap', | |
| longname: 'rowGap', | |
| }, | |
| { | |
| shortname: 'xgap', | |
| longname: 'columnGap', | |
| }, | |
| { | |
| shortname: 'bgColor', | |
| longname: 'backgroundColor', | |
| }, | |
| { | |
| shortname: 'radius', | |
| longname: 'borderRadius', | |
| }, | |
| { | |
| shortname: 'overscroll', | |
| longname: 'overscrollBehavior', | |
| }, | |
| { | |
| shortname: 'overscrollX', | |
| longname: 'overscrollBehaviorX', | |
| }, | |
| { | |
| shortname: 'overscrollY', | |
| longname: 'overscrollBehaviorY', | |
| }, | |
| ]; | |
| function longName(value: string): string { | |
| const object = shortName.find(data => data?.shortname === value); | |
| return object ? object.longname : value; | |
| } | |
| function converter(value: string | number): string { | |
| return typeof value === 'number' ? `${value}rem` : value; | |
| } | |
| function className(value: string): string { | |
| const property = longName(value); | |
| return property.replace(/[A-Z]/g, match => `-${match.toLowerCase()}`); | |
| } | |
| function css(props: Record<string, string>): string { | |
| return Object.entries(props) | |
| .map(([key, value]) => `${className(key)}: ${converter(value)};`) | |
| .join(';'); | |
| } | |
| function Title<E extends React.ElementType = typeof __DEFAULT_ELEMENT__>({ | |
| children, | |
| as, | |
| cls, | |
| hover, | |
| ...props | |
| }: GenericProps<E>) { | |
| const Component = as || __DEFAULT_ELEMENT__; | |
| return ( | |
| <Fragment> | |
| <Component className={clsx('timboo', cls)} {...props}> | |
| {children} | |
| </Component> | |
| <style jsx>{` | |
| .timboo { | |
| ${css(props)} | |
| } | |
| .timboo:hover { | |
| ${css(hover ?? {})} | |
| } | |
| `}</style> | |
| </Fragment> | |
| ); | |
| } | |
| export default Title; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment