info card update

This commit is contained in:
Nate Kelley 2025-02-24 17:40:29 -07:00
parent 3574051205
commit c075820d73
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
15 changed files with 250 additions and 119 deletions

View File

@ -15,9 +15,11 @@ const preview: Preview = {
decorators: [
(Story) => {
return (
<BusterStyleProvider>
<Story />
</BusterStyleProvider>
<div>
<BusterStyleProvider>
<Story />
</BusterStyleProvider>
</div>
);
}
]

View File

@ -1,7 +1,7 @@
import React from 'react';
import { Text } from '@/components/ui/text';
import Link from 'next/link';
import { BusterFrameLogoWithText } from '@/assets';
import { BusterLogoWithText } from '@/assets/svg/BusterLogoWithText';
import { BUSTER_HOME_PAGE } from '@/routes/externalRoutes';
export const WelcomeToBuster: React.FC<{
@ -12,7 +12,7 @@ export const WelcomeToBuster: React.FC<{
<div>
<div className="w-[130px]">
<Link href={BUSTER_HOME_PAGE}>
<BusterFrameLogoWithText />
<BusterLogoWithText />
</Link>
</div>
<div className="mt-24">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.3 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,34 @@
import type { Meta, StoryObj } from '@storybook/react';
import { BusterLogo } from './BusterLogo';
import { BusterLogoWithText } from './BusterLogoWithText';
const meta: Meta<typeof BusterLogo> = {
title: 'Base/Logos',
tags: ['autodocs'],
argTypes: {
className: { control: 'text' }
}
};
export default meta;
type Story = StoryObj<typeof BusterLogo>;
export const DefaultBusterLogo: Story = {
render: (args) => <BusterLogo {...args} />
};
type BusterLogoNewStory = StoryObj<typeof BusterLogoWithText>;
export const DefaultBusterLogoWithText: BusterLogoNewStory = {
render: (args) => <BusterLogoWithText {...args} />,
args: {
color: 'currentColor'
}
};
export const CustomColorBusterLogoWithText: BusterLogoNewStory = {
render: (args) => <BusterLogoWithText {...args} />,
args: {
color: '#FF0000'
}
};

View File

@ -36,7 +36,7 @@ const sizeVariants = {
};
export const buttonVariants = cva(
'inline-flex items-center overflow-hidden text-base justify-center gap-[5px] shadow-btn rounded transition-all duration-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:cursor-not-allowed data-[loading=true]:cursor-progress',
'inline-flex items-center overflow-hidden text-base justify-center gap-[5px] shadow rounded transition-all duration-100 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:cursor-not-allowed data-[loading=true]:cursor-progress',
{
variants: {
buttonType: buttonTypeClasses,

View File

@ -0,0 +1,86 @@
import type { Meta, StoryObj } from '@storybook/react';
import { InfoCard } from './InfoCard';
import { BellOutlined } from '@ant-design/icons';
import { faker } from '@faker-js/faker';
const meta: Meta<typeof InfoCard> = {
title: 'Base/InfoCard',
component: InfoCard,
tags: ['autodocs'],
args: {
title: faker.lorem.sentence(),
description: faker.lorem.paragraph(),
icon: <BellOutlined />,
onClick: () => {}
},
argTypes: {
variant: {
control: 'select',
options: ['default', 'gray', 'ghost']
},
size: {
control: 'select',
options: ['default']
},
iconPosition: {
control: 'select',
options: ['top', 'center', 'bottom', 'absolute-top']
},
title: {
control: 'text'
},
description: {
control: 'text'
},
selected: {
control: 'boolean'
}
}
};
export default meta;
type Story = StoryObj<typeof InfoCard>;
export const Default: Story = {
args: {
title: 'Notifications',
description: 'You have 3 unread messages',
icon: <BellOutlined className="text-primary text-xl" />,
iconPosition: 'center'
}
};
export const TopIcon: Story = {
args: {
title: 'System Status',
description: 'All systems are operational',
icon: <BellOutlined className="text-success text-xl" />,
iconPosition: 'top'
}
};
export const BottomIcon: Story = {
args: {
title: 'Updates Available',
description: 'New version 2.0 is ready to install',
icon: <BellOutlined className="text-warning text-xl" />,
iconPosition: 'bottom'
}
};
export const AbsoluteTopIcon: Story = {
args: {
title: 'Important Notice',
description: 'Please review your account settings',
icon: <BellOutlined className="text-danger text-xl" />,
iconPosition: 'absolute-top'
}
};
export const NoIcon: Story = {
args: {
title: 'Simple Card',
description: 'A card without an icon',
icon: null
}
};

View File

@ -0,0 +1,102 @@
import { cn } from '@/lib/classMerge';
import { cva, type VariantProps } from 'class-variance-authority';
import React from 'react';
const infoCardVariants = cva('rounded relative flex gap-1 w-full h-full justify-between', {
variants: {
size: {
default: 'px-4 py-3.5'
},
variant: {
default: 'border bg-background shadow-sm',
gray: 'border bg-item-hover shadow-sm',
ghost: 'border-none bg-transparent shadow-none'
},
selectable: {
true: 'cursor-pointer',
false: ''
},
selected: {
true: '',
false: ''
}
},
compoundVariants: [
{
selectable: true,
variant: 'default',
className: 'hover:bg-item-hover'
},
{
selectable: true,
variant: 'gray',
className: 'hover:bg-item-active'
},
{
selected: true,
variant: 'default',
className: 'bg-item-hover'
},
{
selected: true,
variant: 'gray',
className: 'bg-item-active'
}
]
});
interface InfoCardProps extends React.HTMLAttributes<HTMLDivElement> {
variant?: VariantProps<typeof infoCardVariants>['variant'];
size?: VariantProps<typeof infoCardVariants>['size'];
title: string;
description: string;
icon: React.ReactNode;
iconPosition?: 'top' | 'center' | 'bottom' | 'absolute-top';
onClick?: () => void;
selected?: boolean;
}
export const InfoCard: React.FC<InfoCardProps> = React.memo(
({
size = 'default',
variant = 'default',
title,
description,
icon,
iconPosition = 'center',
className,
onClick,
selected = false,
...props
}) => {
return (
<div
className={cn(
infoCardVariants({ size, variant, selectable: !!onClick, selected }),
className
)}
{...props}>
<div className="flex flex-1 flex-col gap-1.5">
<h3 className="text-foreground text-base">{title}</h3>
<p className="text-gray-dark text-xs">{description}</p>
</div>
{icon && (
<div
className={cn(
'text-icon-color hover:text-foreground flex min-h-full',
iconPosition === 'absolute-top' ? 'absolute top-3 right-3' : 'pl-4',
{
'items-start': iconPosition === 'top',
'items-center': iconPosition === 'center',
'items-end': iconPosition === 'bottom'
}
)}>
<span className="h-fit">{icon}</span>
</div>
)}
</div>
);
}
);
InfoCard.displayName = 'InfoCard';

View File

@ -1,7 +0,0 @@
<svg width="3770" height="4353" viewBox="0 0 3770 4353" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="3770" height="4353" fill="white"/>
<path d="M623.305 3160.39C330.978 3160.39 94 2923.4 94 2631.06V529.326C94 236.987 330.978 0 623.305 0C915.632 0 1152.61 236.987 1152.61 529.326V2631.06C1152.61 2923.4 915.632 3160.39 623.305 3160.39Z" fill="#919191"/>
<path d="M250.326 3029.37C43.6196 2822.65 43.6195 2487.5 250.326 2280.79L1564.38 966.678C1771.09 759.964 2106.23 759.964 2312.93 966.678C2519.64 1173.39 2519.64 1508.54 2312.93 1715.26L998.876 3029.37C792.17 3236.08 457.033 3236.08 250.326 3029.37Z" fill="#7E7E7E"/>
<path d="M1493.99 4197.96C1287.29 3991.25 1287.29 3656.1 1493.99 3449.38L2763.1 2180.23C2969.81 1973.51 3304.95 1973.51 3511.65 2180.23C3718.36 2386.94 3718.36 2722.09 3511.65 2928.8L2242.55 4197.96C2035.84 4404.68 1700.7 4404.68 1493.99 4197.96Z" fill="#605E5E"/>
<path d="M3525.97 2918.35C3319.26 3125.06 2984.13 3125.06 2777.42 2918.35L1558.02 1698.9C1351.31 1492.19 1351.31 1157.04 1558.02 950.321C1764.73 743.607 2099.86 743.607 2306.57 950.321L3525.97 2169.77C3732.68 2376.48 3732.68 2711.63 3525.97 2918.35Z" fill="#D7D7D7"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -3,7 +3,7 @@ import { Button, ConfigProvider } from 'antd';
import Link from 'next/link';
import { BusterRoutes, BusterRoutesWithArgsRoute } from '@/routes';
import { AppMaterialIcons } from '@/components/ui';
import { BusterLogoNew } from '@/assets/svg/BusterLogoNew';
import { BusterLogoNew } from '@/assets/svg/BusterLogoWithText';
import { AppTooltip } from '@/components/ui';
import { useHotkeys } from 'react-hotkeys-hook';
import { useAntToken } from '@/styles/useAntToken';

View File

@ -2,7 +2,6 @@ import type { IBusterMetric } from '@/context/Metrics';
import { downloadImageData, exportElementToImage } from './exportUtils';
import { createRoot } from 'react-dom/client';
import { timeout } from './timeout';
import { BusterLogoWithTextBW } from '@/assets/svg/BusterLogoWithTextBW';
import React, { useEffect, useRef } from 'react';
import { BusterChart } from '@/components/ui/charts';
import type { BusterMetricData } from '@/context/MetricData';
@ -196,7 +195,7 @@ export const PreviewImageReactComponent: React.FC<{
? 'drop-shadow(0 0 8px rgba(255, 255, 255, 0.15))'
: 'drop-shadow(0 0 8px rgba(0, 0, 0, 0.1))'
}}>
<BusterLogoWithTextBW />
<></>
</div>
);

View File

@ -10,7 +10,7 @@
--font-mono: Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
/* shadows */
--shadow-btn: 0px 1px 4px 0px rgba(0, 0, 0, 0.05);
--shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.05);
/* border */
--default-border-width: 0.5px;