diff --git a/src/components/Avatar/Avatar.stories.tsx b/src/components/Avatar/Avatar.stories.tsx index c888a058..5f1f6786 100644 --- a/src/components/Avatar/Avatar.stories.tsx +++ b/src/components/Avatar/Avatar.stories.tsx @@ -14,21 +14,13 @@ export const Default = () => ( ) /** - * Size can be controlled through the `css` prop, the default is `$7`. + * Size can be controlled through the `size` prop, with values `small`, `medium` (default) and `large`. */ export const Size = () => ( - - - - + + + + ) diff --git a/src/components/Avatar/Avatar.tsx b/src/components/Avatar/Avatar.tsx index 4896b2e3..5a42c279 100644 --- a/src/components/Avatar/Avatar.tsx +++ b/src/components/Avatar/Avatar.tsx @@ -1,16 +1,9 @@ import { Fallback, Image, Root } from '@radix-ui/react-avatar' +import { VariantProps } from '@stitches/react' import React from 'react' import type { CSS } from '../../stitches.config' import { styled } from '../../stitches.config' -interface AvatarProps { - src?: string - alt?: string - css?: CSS - color?: CSS['color'] - backgroundColor?: CSS['backgroundColor'] -} - const StyledRoot = styled(Root, { display: 'inline-flex', alignItems: 'center', @@ -20,8 +13,16 @@ const StyledRoot = styled(Root, { userSelect: 'none', borderRadius: '$round', - width: '$7', - height: '$7', + variants: { + size: { + small: { size: '$5' }, + medium: { size: '$7' }, + large: { size: '$9' }, + }, + }, + defaultVariants: { + size: 'medium', + }, }) const StyledImage = styled(Image, { @@ -38,6 +39,14 @@ const StyledFallback = styled(Fallback, { justifyContent: 'center', }) +interface AvatarProps extends VariantProps { + src?: string + alt?: string + css?: CSS + color?: CSS['color'] + backgroundColor?: CSS['backgroundColor'] +} + /** * The Avatar should be used for profile images. If an image is not available initials can be used. */ diff --git a/src/components/Skeleton/Skeleton.stories.tsx b/src/components/Skeleton/Skeleton.stories.tsx index 9049aa84..bb9390e3 100644 --- a/src/components/Skeleton/Skeleton.stories.tsx +++ b/src/components/Skeleton/Skeleton.stories.tsx @@ -1,5 +1,5 @@ import React from 'react' - +import { Flex } from '../Flex' import { Story, Meta } from '@storybook/react' import { Skeleton } from '.' @@ -11,23 +11,38 @@ export default { const Template: Story = (args) => export const Primary = Template.bind({}) -export const Avatar = Template.bind({}) -Avatar.args = { - variant: 'avatar', -} + export const Text = Template.bind({}) Text.args = { variant: 'text', } + export const Title = Template.bind({}) Title.args = { variant: 'title', } +/** An alternative animation, `pulse`, is available */ +export const Animation = Template.bind({}) +Animation.args = { + variant: 'title', + animation: 'pulse', +} + +/** The `avatar` variant also supports an additional size prop to reflect the sizing on the `Avatar` component. */ +export const Avatar = () => ( + + + + + +) + +/** The `button` variant also supports an additional size prop to reflect the sizing on the `Button` component. */ export const Buttons = () => ( - <> + - + ) diff --git a/src/components/Skeleton/Skeleton.tsx b/src/components/Skeleton/Skeleton.tsx index 24a0c850..a392e882 100644 --- a/src/components/Skeleton/Skeleton.tsx +++ b/src/components/Skeleton/Skeleton.tsx @@ -1,21 +1,22 @@ -import type * as Polymorphic from '@radix-ui/react-polymorphic' -import React, { forwardRef } from 'react' -import type { CSSProps, VariantProps } from '../../stitches.config' -import { styled, keyframes } from '../../stitches.config' +import { keyframes, styled } from '../../stitches.config' const DEFAULT_TAG = 'div' +const BASE_COLOR = '$grey5' +const HIGHLIGHT_COLOR = '$grey7' + export const ripple = keyframes({ '0%': { - backgroundPosition: '-200px 0', + backgroundPosition: '-1000px 0', }, '100%': { - backgroundPosition: 'calc(200px + 100%) 0', + backgroundPosition: '1000px 0', }, }) export const pulse = keyframes({ '0%': { opacity: 0 }, + '50%': { opacity: '100%' }, '100%': { opacity: '100%' }, }) @@ -23,18 +24,11 @@ export const pulse = keyframes({ * StyledSkeleton base component */ export const Skeleton = styled(DEFAULT_TAG, { - backgroundColor: '$grey4', + backgroundColor: BASE_COLOR, position: 'relative', overflow: 'hidden', '&::after': { - animationName: `${pulse}`, - animationDuration: '500ms', - animationDirection: 'alternate', - animationIterationCount: 'infinite', - animationTimingFunction: 'ease-in-out', - backgroundColor: '$slate6', - borderRadius: 'inherit', bottom: 0, content: '""', left: 0, @@ -42,7 +36,6 @@ export const Skeleton = styled(DEFAULT_TAG, { right: 0, top: 0, }, - variants: { variant: { avatar: { @@ -50,13 +43,13 @@ export const Skeleton = styled(DEFAULT_TAG, { size: '$7', }, text: { - height: '$1', + height: '$4', }, title: { height: '$5', }, heading: { - height: '$3', + height: '$7', }, button: { borderRadius: '$default', @@ -69,6 +62,38 @@ export const Skeleton = styled(DEFAULT_TAG, { default: {}, large: {}, }, + animation: { + ripple: { + '&::after': { + animationName: `${ripple}`, + animationDuration: '2s', + animationDirection: 'normal', + animationIterationCount: 'infinite', + animationTimingFunction: 'ease-in-out', + backgroundImage: `linear-gradient( + to right, + ${BASE_COLOR} 4%, + ${HIGHLIGHT_COLOR} 25%, + ${BASE_COLOR} 35% + )`, + backgroundSize: '1000px 100%', + backgroundRepeat: 'no-repeat', + borderRadius: 'inherit', + lineHeight: '$default', + width: '100%', + }, + }, + pulse: { + '&::after': { + animationName: `${pulse}`, + animationDuration: '1s', + animationDirection: 'alternate', + animationIterationCount: 'infinite', + animationTimingFunction: 'ease-in-out', + backgroundColor: HIGHLIGHT_COLOR, + }, + }, + }, }, compoundVariants: [ { @@ -87,8 +112,23 @@ export const Skeleton = styled(DEFAULT_TAG, { width: '$9', }, }, + { + variant: 'avatar', + size: 'small', + css: { + size: '$5', + }, + }, + { + variant: 'avatar', + size: 'large', + css: { + size: '$9', + }, + }, ], defaultVariants: { variant: 'text', + animation: 'ripple', }, })