From d7c75d9c4fc4f76b5b0952112a364384fae25692 Mon Sep 17 00:00:00 2001 From: storywithoutend Date: Tue, 14 Nov 2023 16:52:40 +0800 Subject: [PATCH] checkpoint --- .../src/components/atoms/Avatar/Avatar.tsx | 51 ++++++-- .../src/components/atoms/Avatar/styles.css.ts | 11 ++ components/src/components/atoms/Box/Box.tsx | 11 +- .../src/components/atoms/Button/Button.tsx | 23 ++-- components/src/components/atoms/Card/Card.tsx | 8 +- .../atoms/DynamicPopover/DynamicPopover.tsx | 8 +- .../atoms/DynamicPopover/style.css.ts | 7 ++ components/src/components/atoms/Tag/Tag.tsx | 10 +- .../atoms/Typography/Typography.tsx | 10 +- .../molecules/Dropdown/Dropdown.tsx | 112 +++++++++--------- .../components/molecules/Profile/Profile.tsx | 12 +- components/src/css/rainbow-spinkles.css.ts | 22 +--- .../src/css/recipes/statusBorder.css.ts | 2 +- components/src/css/recipes/statusDot.css.ts | 2 +- components/src/tokens/border.ts | 12 +- components/src/utils/removeNullishProps.ts | 9 ++ docs/src/reference/mdx/atoms/Avatar.docs.mdx | 36 ++++-- 17 files changed, 207 insertions(+), 139 deletions(-) create mode 100644 components/src/components/atoms/Avatar/styles.css.ts create mode 100644 components/src/components/atoms/DynamicPopover/style.css.ts create mode 100644 components/src/utils/removeNullishProps.ts diff --git a/components/src/components/atoms/Avatar/Avatar.tsx b/components/src/components/atoms/Avatar/Avatar.tsx index 0c7b91a9..d3c0bb7b 100644 --- a/components/src/components/atoms/Avatar/Avatar.tsx +++ b/components/src/components/atoms/Avatar/Avatar.tsx @@ -2,7 +2,11 @@ import * as React from 'react' import { rainbowSprinkles } from '@/src/css/rainbow-spinkles.css' -import { Box, BoxProps } from '../Box' +import { rawColorToRGBA } from '@/src/tokens/color3' + +import { Box, type BoxProps } from '../Box' +import { avatar } from './styles.css' +import { CheckSVG } from '../..' type NativeImgAttributes = React.ImgHTMLAttributes @@ -10,17 +14,20 @@ type Shape = 'circle' | 'square' interface Container { $shape: Shape + $size: BoxProps['wh'] } -const Container = ({ $shape, ...props }: BoxProps & Container) => ( +const Container = ({ $shape, $size, ...props }: BoxProps & Container) => ( ) @@ -58,7 +65,13 @@ export type Props = { /** If true sets the component into disabled format. */ disabled?: boolean /** An element that overlays the avatar */ - overlay?: React.ReactNode + checked?: boolean + /** An svg to overlay over the avatar */ + icon?: React.ReactElement + /** The deconding attribute of an img element */ + decoding?: NativeImgAttributes['decoding'] + /** A custom sizing for the avatar */ + size?: BoxProps['wh'] } & Omit export const Avatar = ({ @@ -68,7 +81,9 @@ export const Avatar = ({ placeholder, decoding = 'async', disabled = false, - overlay, + icon, + checked, + size, ...props }: Props) => { const ref = React.useRef(null) @@ -114,9 +129,26 @@ export const Avatar = ({ ...props, }) + const overlay = React.useMemo(() => { + if (disabled || (!icon && !checked)) return null + return ( + + } wh="40%" /> + + ) + }, [checked, disabled, icon]) return ( - - {overlay} + {!isImageVisible && ( setShowImage(false)} onLoad={() => setShowImage(true)} /> + {overlay} ) } diff --git a/components/src/components/atoms/Avatar/styles.css.ts b/components/src/components/atoms/Avatar/styles.css.ts new file mode 100644 index 00000000..a36ad451 --- /dev/null +++ b/components/src/components/atoms/Avatar/styles.css.ts @@ -0,0 +1,11 @@ +import { globalStyle, style } from '@vanilla-extract/css' + +export const avatar = style({}) + +globalStyle(`${avatar} > * `, { + position: 'absolute', + top: 0, + left: 0, + width: '100%', + height: '100%', +}) diff --git a/components/src/components/atoms/Box/Box.tsx b/components/src/components/atoms/Box/Box.tsx index 177b2ffc..4f5edffd 100644 --- a/components/src/components/atoms/Box/Box.tsx +++ b/components/src/components/atoms/Box/Box.tsx @@ -8,7 +8,10 @@ import React, { } from 'react' import classNames from 'clsx' -import { Sprinkles, rainbowSprinkles } from '../../../css/rainbow-spinkles.css' +import { + type Sprinkles, + rainbowSprinkles, +} from '@/src/css/rainbow-spinkles.css' type HTMLProperties = Omit< AllHTMLAttributes, @@ -18,9 +21,9 @@ type HTMLProperties = Omit< export type BoxProps = Sprinkles & HTMLProperties & { as?: ElementType | ReactElement } -export const Box = forwardRef( +export const Box = forwardRef( ( - { as: _as, className: _className, style: _style, children, ...props }, + { as: _as, className: _className, style: _style, children, log, ...props }, ref, ) => { const { @@ -34,10 +37,12 @@ export const Box = forwardRef( if (isValidElement(_as)) { const as = _as as ReactElement + if (log) console.log('as', className, style, otherProps) return cloneElement(as, { className, style, ...otherProps }) } const as = _as as ElementType const Component = as || 'div' + if (log) console.log('as', className, style, otherProps) return ( {children} diff --git a/components/src/components/atoms/Button/Button.tsx b/components/src/components/atoms/Button/Button.tsx index ed16a7b1..7d7d9a5a 100644 --- a/components/src/components/atoms/Button/Button.tsx +++ b/components/src/components/atoms/Button/Button.tsx @@ -2,10 +2,10 @@ import * as React from 'react' import { P, match } from 'ts-pattern' -import { Space } from '@/src/tokens' - import { scale, translateY } from '@/src/css/utils/common' +import { removeNullishProps } from '@/src/utils/removeNullishProps' + import { ColorStyle, WithColorStyle, @@ -47,8 +47,6 @@ type BaseProps = { pressed?: boolean /** If true, adds a box-shadow */ shadow?: boolean - /** A space value for the width of the button */ - width?: Space /** If true, makes inner div full width */ fullWidthContent?: boolean /** When set, shows a count indicator on the button */ @@ -58,7 +56,7 @@ type BaseProps = { /** Show indicator that button has extra info via tooltip. */ shouldShowTooltipIndicator?: boolean color?: Color -} & Omit +} & Omit type WithAnchor = { /** The href attribute for the anchor element. */ @@ -84,7 +82,6 @@ type ButtonBoxProps = { $colorStyle: WithColorStyle['colorStyle'] $color?: Color $hasCounter?: boolean - $width: any } const ButtonBox = React.forwardRef< HTMLButtonElement, @@ -98,7 +95,6 @@ const ButtonBox = React.forwardRef< $size = 'medium', $colorStyle = 'accentPrimary', $hasCounter, - $width = '$full', $color, as, ...props @@ -141,7 +137,7 @@ const ButtonBox = React.forwardRef< height={getValueForSize($size, 'height')} justifyContent="center" position="relative" - px={$hasCounter ? '$12' : getValueForSize($size, 'px')} + // px={$hasCounter ? '$12' : getValueForSize($size, 'px')} ref={ref} transform={{ base: translateY(0), @@ -155,9 +151,12 @@ const ButtonBox = React.forwardRef< width={ ['square', 'circle'].includes($shape) ? getValueForSize($size, 'height') - : $width + : '$full' } - {...props} + {...{ + px: $hasCounter ? '$12' : getValueForSize($size, 'px'), + ...props, + }} /> ), ) @@ -267,7 +266,6 @@ export const Button = React.forwardRef( onClick, pressed = false, shadow = false, - width, fullWidthContent, count, color, @@ -322,7 +320,6 @@ export const Button = React.forwardRef( $shadow={shadow} $shape={shape} $size={size} - $width={width} as={asProp as any} disabled={disabled} href={href} @@ -335,7 +332,7 @@ export const Button = React.forwardRef( zIndex={zIndex} //eslint-disable-next-line react/jsx-sort-props onClick={onClick} - {...props} + {...removeNullishProps(props)} > {shouldShowTooltipIndicator && ( diff --git a/components/src/components/atoms/Card/Card.tsx b/components/src/components/atoms/Card/Card.tsx index cb07ecc9..1a1f1f72 100644 --- a/components/src/components/atoms/Card/Card.tsx +++ b/components/src/components/atoms/Card/Card.tsx @@ -1,11 +1,13 @@ import * as React from 'react' +import { removeNullishProps } from '@/src/utils/removeNullishProps' + import { Typography } from '../Typography' import { Box, BoxProps } from '../Box/Box' export type Props = { title?: string -} & NativeDivProps +} & BoxProps const ContainerBox = (props: BoxProps) => ( ( /> ) -type NativeDivProps = React.HTMLAttributes - export const Card = ({ title, children, ...props }: Props) => { return ( - + {title && {title}} {children} diff --git a/components/src/components/atoms/DynamicPopover/DynamicPopover.tsx b/components/src/components/atoms/DynamicPopover/DynamicPopover.tsx index d89f421b..a452583a 100644 --- a/components/src/components/atoms/DynamicPopover/DynamicPopover.tsx +++ b/components/src/components/atoms/DynamicPopover/DynamicPopover.tsx @@ -6,6 +6,7 @@ import { debounce } from 'lodash' import { Portal } from '../Portal' import { Box, BoxProps } from '../Box/Box' import { getValueForTransitionState } from './utils/getValueForTransitionState' +import { container } from './style.css' export type DynamicPopoverSide = 'top' | 'right' | 'bottom' | 'left' @@ -170,12 +171,10 @@ const PopoverBox = React.forwardRef( ) => ( toggle(false) }, [isControlled, isOpen]) const [state, toggle] = useTransition({ diff --git a/components/src/components/atoms/DynamicPopover/style.css.ts b/components/src/components/atoms/DynamicPopover/style.css.ts new file mode 100644 index 00000000..698533ee --- /dev/null +++ b/components/src/components/atoms/DynamicPopover/style.css.ts @@ -0,0 +1,7 @@ +import { ComplexStyleRule, style } from '@vanilla-extract/css' + +export const container = style({ + WebkitBackfaceVisibility: 'hidden', + MozBackfaceVisibility: 'hidden', + backfaceVisibility: 'hidden', +} as ComplexStyleRule) diff --git a/components/src/components/atoms/Tag/Tag.tsx b/components/src/components/atoms/Tag/Tag.tsx index c78879cb..f6255f16 100644 --- a/components/src/components/atoms/Tag/Tag.tsx +++ b/components/src/components/atoms/Tag/Tag.tsx @@ -2,11 +2,11 @@ import * as React from 'react' import { translateY } from '@/src/css/utils/common' -import { WithColorStyle, getValueForColorStyle } from './utils/withColorStyle' +import { removeNullishProps } from '@/src/utils/removeNullishProps' -import { Box } from '../Box/Box' +import { WithColorStyle, getValueForColorStyle } from './utils/withColorStyle' -type NativeDivProps = React.HTMLAttributes +import { Box, BoxProps } from '../Box/Box' export type Props = { /** Element type of container */ @@ -15,7 +15,7 @@ export type Props = { hover?: boolean /** Size of element */ size?: 'small' | 'medium' -} & NativeDivProps & +} & Omit & WithColorStyle export const Tag = ({ @@ -55,7 +55,7 @@ export const Tag = ({ transitionProperty="color, border-color, background-color, transform" transitionTimingFunction="$inOut" width="$max" - {...props} + {...removeNullishProps(props)} > {children} diff --git a/components/src/components/atoms/Typography/Typography.tsx b/components/src/components/atoms/Typography/Typography.tsx index e0fce815..6e33f94e 100644 --- a/components/src/components/atoms/Typography/Typography.tsx +++ b/components/src/components/atoms/Typography/Typography.tsx @@ -4,7 +4,9 @@ import { Font, FontSize, FontWeight } from '@/src/tokens/typography' import { Color, WithColor, validateColor } from '@/src/interfaces/withColor' -import { Box, BoxProps } from '../Box/Box' +import { removeNullishProps } from '@/src/utils/removeNullishProps' + +import { Box, type BoxProps } from '../Box/Box' import { FontVariant, getValueForVariant } from './utils/getValueForVariant' type ContainerProps = { @@ -22,7 +24,6 @@ const ContainerBox = React.forwardRef( ref, ) => ( ( ref={ref} textOverflow={$ellipsis ? 'ellipsis' : undefined} whiteSpace={$ellipsis ? 'nowrap' : undefined} + {...props} /> ), ) @@ -77,7 +79,6 @@ export const Typography = React.forwardRef( as, children, ellipsis, - className = '', fontVariant = 'body', font = 'sans', color = 'textPrimary', @@ -89,16 +90,15 @@ export const Typography = React.forwardRef( ) => { return ( {children} diff --git a/components/src/components/molecules/Dropdown/Dropdown.tsx b/components/src/components/molecules/Dropdown/Dropdown.tsx index f4adce70..220ca676 100644 --- a/components/src/components/molecules/Dropdown/Dropdown.tsx +++ b/components/src/components/molecules/Dropdown/Dropdown.tsx @@ -149,61 +149,61 @@ interface MenuButtonProps { $showIndicator?: boolean | Colors } -const MenuButton = ({ - $color, - $icon, - $showIndicator, - disabled, - children, - ...props -}: BoxProps & MenuButtonProps) => ( - - {$icon && ( - - )} - {children} - {$showIndicator && ( - - )} - +const MenuButton = React.forwardRef( + ({ $color, $icon, $showIndicator, disabled, children, ...props }, ref) => ( + + {$icon && ( + + )} + {children} + {$showIndicator && ( + + )} + + ), ) const DropdownChild: React.FC<{ @@ -407,7 +407,7 @@ const DropdownButton: React.FC = ({ pressed={isOpen} ref={buttonRef} suffix={chevron && } - width="fit" + width="$fit" onClick={() => setIsOpen((prev) => !prev)} {...buttonPropsWithIndicator} > diff --git a/components/src/components/molecules/Profile/Profile.tsx b/components/src/components/molecules/Profile/Profile.tsx index f2d54660..f98ee65d 100644 --- a/components/src/components/molecules/Profile/Profile.tsx +++ b/components/src/components/molecules/Profile/Profile.tsx @@ -4,6 +4,8 @@ import { Colors } from '@/src/tokens' import { brightness, translateY } from '@/src/css/utils/common' +import { removeNullishProps } from '@/src/utils/removeNullishProps' + import { getTestId, shortenAddress } from '../../../utils/utils' import { Typography } from '../..' @@ -48,7 +50,6 @@ const calculateWidth = (size: Size) => { const Container = React.forwardRef( ({ $size, $hasDropdown, $open, ...props }, ref) => ( ( transitionTimingFunction="$inOut" width={getValueForSize($size, 'width')} zIndex={10} + {...props} /> ), ) @@ -162,11 +164,11 @@ export const Profile = ({ }} > setIsOpen(!isOpen)} + {...removeNullishProps(props)} > @@ -176,12 +178,10 @@ export const Profile = ({ return ( diff --git a/components/src/css/rainbow-spinkles.css.ts b/components/src/css/rainbow-spinkles.css.ts index 40c3e373..43aa9253 100644 --- a/components/src/css/rainbow-spinkles.css.ts +++ b/components/src/css/rainbow-spinkles.css.ts @@ -20,6 +20,7 @@ const responsiveProperties = defineProperties({ defaultCondition: 'base', dynamicProperties: { alignSelf: true, + justifySelf: true, display: true, flexDirection: true, flex: true, @@ -61,6 +62,7 @@ const responsiveProperties = defineProperties({ marginTop: commonVars.space, overflowX: true, overflowY: true, + overflowWrap: true, width: commonVars.space, maxWidth: commonVars.space, minWidth: commonVars.space, @@ -68,7 +70,7 @@ const responsiveProperties = defineProperties({ minHeight: commonVars.space, whiteSpace: true, strokeWidth: commonVars.space, - stroke: true, + stroke: modeVars.color, outline: true, resize: true, textTransform: true, @@ -97,14 +99,15 @@ const responsiveProperties = defineProperties({ maskRepeat: true, maskPosition: true, border: true, + borderWidth: commonVars.borderWidths, + borderStyle: true, + borderColor: modeVars.color, borderRadius: commonVars.radii, borderSpacing: true, - borderStyle: true, borderLeft: true, borderRight: true, borderTop: true, borderBottom: true, - borderColor: modeVars.color, borderBottomColor: modeVars.color, borderLeftColor: modeVars.color, borderRightColor: modeVars.color, @@ -123,19 +126,6 @@ const responsiveProperties = defineProperties({ transitionDuration: commonVars.transitionDuration, transitionProperty: true, }, - staticProperties: { - borderWidth: { - '0': '0px', - '1x': '1px', - '2x': '2px', - '3x': '3px', - '10x': '10px', - }, - WebkitBackfaceVisibility: { hidden: 'hidden' }, - MozBackfaceVisibility: { hidden: 'hidden' }, - WebkitTransform: { base: 'translate3d(0, 0, 0)' }, - MozTransform: { base: 'translate3d(0, 0, 0)' }, - }, shorthands: { bg: ['backgroundColor'], p: ['padding'], diff --git a/components/src/css/recipes/statusBorder.css.ts b/components/src/css/recipes/statusBorder.css.ts index 5c933ec9..c35bebfd 100644 --- a/components/src/css/recipes/statusBorder.css.ts +++ b/components/src/css/recipes/statusBorder.css.ts @@ -5,7 +5,7 @@ import { modeVars } from '../theme.css' export const statusBorder = recipe({ base: { borderColor: modeVars.color.border, - borderWidth: '1px', + borderWidth: '$1x', borderStyle: 'solid', selectors: { '&:not(:disabled):focus-within': { diff --git a/components/src/css/recipes/statusDot.css.ts b/components/src/css/recipes/statusDot.css.ts index 94d40cae..c44bdb90 100644 --- a/components/src/css/recipes/statusDot.css.ts +++ b/components/src/css/recipes/statusDot.css.ts @@ -15,7 +15,7 @@ export const statusDot = recipe({ height: commonVars.space['4'], backgroundColor: modeVars.color.bluePrimary, opacity: 0, - borderWidth: '2px', + borderWidth: '$2x', borderStyle: 'solid', borderColor: modeVars.color.backgroundPrimary, transform: 'scale(0.3)', diff --git a/components/src/tokens/border.ts b/components/src/tokens/border.ts index cf6ef171..c1a0e215 100644 --- a/components/src/tokens/border.ts +++ b/components/src/tokens/border.ts @@ -5,15 +5,9 @@ export const borderStyles = { export const borderWidths = { '0': '0px', - px: '1px', - '0.375': '0.09375rem', - '0.5': '0.125rem', - '0.75': '0.1875rem', - '1': '0.25rem', - '1.25': '0.3125rem', - '1.5': '0.375rem', - '1.75': '0.4375rem', - '2': '0.5rem', + '1x': '1px', + '2x': '2px', + '10x': '10px', } export const radii = { diff --git a/components/src/utils/removeNullishProps.ts b/components/src/utils/removeNullishProps.ts new file mode 100644 index 00000000..6558c7bb --- /dev/null +++ b/components/src/utils/removeNullishProps.ts @@ -0,0 +1,9 @@ +import { BoxProps } from '../components' + +export const removeNullishProps = (props: BoxProps): object => { + const keys = Object.keys(props) as (keyof BoxProps)[] + return keys.reduce( + (acc, cur) => (props[cur] ? { ...acc, [cur]: props[cur] } : acc), + {}, + ) +} diff --git a/docs/src/reference/mdx/atoms/Avatar.docs.mdx b/docs/src/reference/mdx/atoms/Avatar.docs.mdx index 76259277..e973b70b 100644 --- a/docs/src/reference/mdx/atoms/Avatar.docs.mdx +++ b/docs/src/reference/mdx/atoms/Avatar.docs.mdx @@ -76,13 +76,35 @@ The placeholder is shown if the src property is undefined or if an error occurs ```tsx live=true -
- } - src={avatars.noun97} - /> -
+ + + + } + src={avatars.noun97} + wh="$10" + /> + } + src={avatars.noun97} + wh="$10" + />
```