mirror of https://github.com/buster-so/buster.git
make more resilent indicator
This commit is contained in:
parent
419378356a
commit
bef209244d
|
@ -0,0 +1,52 @@
|
||||||
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
import { StatusIndicator } from './StatusIndicator';
|
||||||
|
|
||||||
|
const meta = {
|
||||||
|
title: 'Base/StatusIndicator',
|
||||||
|
component: StatusIndicator,
|
||||||
|
parameters: {
|
||||||
|
layout: 'centered'
|
||||||
|
},
|
||||||
|
tags: ['autodocs']
|
||||||
|
} satisfies Meta<typeof StatusIndicator>;
|
||||||
|
|
||||||
|
export default meta;
|
||||||
|
type Story = StoryObj<typeof meta>;
|
||||||
|
|
||||||
|
export const Loading: Story = {
|
||||||
|
args: {
|
||||||
|
status: 'loading'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Completed: Story = {
|
||||||
|
args: {
|
||||||
|
status: 'completed'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Failed: Story = {
|
||||||
|
args: {
|
||||||
|
status: 'failed'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Story that shows all states side by side
|
||||||
|
export const AllStates: Story = {
|
||||||
|
render: () => (
|
||||||
|
<div className="flex gap-4">
|
||||||
|
<div className="flex flex-col items-center gap-2">
|
||||||
|
<StatusIndicator status="loading" />
|
||||||
|
<span className="text-sm">Loading</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-center gap-2">
|
||||||
|
<StatusIndicator status="completed" />
|
||||||
|
<span className="text-sm">Completed</span>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col items-center gap-2">
|
||||||
|
<StatusIndicator status="failed" />
|
||||||
|
<span className="text-sm">Failed</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
};
|
|
@ -1,8 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { createStyles } from 'antd-style';
|
import { RadioChecked, Radio, CircleWarning } from '../icons';
|
||||||
import { CircleSpinnerLoader } from '@/components/ui/loaders/CircleSpinnerLoader';
|
import { cn } from '@/lib/classMerge';
|
||||||
import { AppMaterialIcons } from '@/components/ui';
|
|
||||||
|
|
||||||
const animationConfig = {
|
const animationConfig = {
|
||||||
initial: { opacity: 0 },
|
initial: { opacity: 0 },
|
||||||
|
@ -13,28 +12,24 @@ const animationConfig = {
|
||||||
|
|
||||||
export const StatusIndicator: React.FC<{ status?: 'completed' | 'loading' | 'failed' }> =
|
export const StatusIndicator: React.FC<{ status?: 'completed' | 'loading' | 'failed' }> =
|
||||||
React.memo(({ status }) => {
|
React.memo(({ status }) => {
|
||||||
const { styles, cx } = useStyles();
|
|
||||||
const inProgress = status === 'loading';
|
const inProgress = status === 'loading';
|
||||||
|
const failed = status === 'failed';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cn(
|
||||||
styles.indicatorContainer,
|
'text-gray-light relative flex h-[11px] w-[11px] items-center justify-center rounded-full transition-all duration-200',
|
||||||
inProgress && 'in-progress',
|
inProgress && 'text-primary',
|
||||||
'relative flex items-center justify-center transition-all duration-300'
|
failed && 'text-danger-foreground'
|
||||||
)}>
|
)}>
|
||||||
<AnimatePresence mode="wait">
|
<AnimatePresence mode="wait">
|
||||||
<motion.div
|
<motion.div
|
||||||
{...animationConfig}
|
{...animationConfig}
|
||||||
className={cx(
|
key={status}
|
||||||
inProgress && 'in-progress',
|
className={cn(
|
||||||
'ml-[0.5px] flex items-center justify-center transition-all duration-300'
|
'ml-[0.5px] flex items-center justify-center transition-all duration-300'
|
||||||
)}>
|
)}>
|
||||||
{inProgress ? (
|
{failed ? <CircleWarning /> : <RadioChecked />}
|
||||||
<AppMaterialIcons icon="circle_with_ring" size={10} />
|
|
||||||
) : (
|
|
||||||
<AppMaterialIcons icon="circle_with_ring" size={10} />
|
|
||||||
)}
|
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
</div>
|
</div>
|
||||||
|
@ -42,17 +37,3 @@ export const StatusIndicator: React.FC<{ status?: 'completed' | 'loading' | 'fai
|
||||||
});
|
});
|
||||||
|
|
||||||
StatusIndicator.displayName = 'StatusIndicator';
|
StatusIndicator.displayName = 'StatusIndicator';
|
||||||
|
|
||||||
const useStyles = createStyles(({ token, css }) => ({
|
|
||||||
indicatorContainer: css`
|
|
||||||
width: 11px;
|
|
||||||
height: 11px;
|
|
||||||
border-radius: 100%;
|
|
||||||
|
|
||||||
color: ${token.colorTextPlaceholder};
|
|
||||||
|
|
||||||
&.in-progress {
|
|
||||||
color: ${token.colorPrimary};
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}));
|
|
||||||
|
|
Loading…
Reference in New Issue