diff --git a/web/.storybook/preview.tsx b/web/.storybook/preview.tsx index 494794ea9..a89ae653c 100644 --- a/web/.storybook/preview.tsx +++ b/web/.storybook/preview.tsx @@ -15,9 +15,11 @@ const preview: Preview = { decorators: [ (Story) => { return ( - - - +
+ + + +
); } ] diff --git a/web/src/app/auth/_LoginComponents/WelcomeSidebar.tsx b/web/src/app/auth/_LoginComponents/WelcomeSidebar.tsx index 024891455..4119d12f8 100644 --- a/web/src/app/auth/_LoginComponents/WelcomeSidebar.tsx +++ b/web/src/app/auth/_LoginComponents/WelcomeSidebar.tsx @@ -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<{
- +
diff --git a/web/src/assets/svg/BusterFrameLogoWithText.tsx b/web/src/assets/svg/BusterFrameLogoWithText.tsx deleted file mode 100644 index 6d9d9a5d0..000000000 --- a/web/src/assets/svg/BusterFrameLogoWithText.tsx +++ /dev/null @@ -1,23 +0,0 @@ -export const BusterFrameLogoWithText = ({ className }: { className?: string }) => { - return ( - - - - - - - - - - - - - ); -}; diff --git a/web/src/assets/svg/BusterLogoNew.tsx b/web/src/assets/svg/BusterLogoNew.tsx deleted file mode 100644 index 898235581..000000000 --- a/web/src/assets/svg/BusterLogoNew.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; - -export const BusterLogoNew: React.FC<{ - onClick?: () => void; - className?: string; - style?: React.CSSProperties; - color?: string; -}> = ({ color = 'currentColor', ...props }) => { - return ( - - - - - ); -}; diff --git a/web/src/assets/svg/BusterLogoWithText.svg b/web/src/assets/svg/BusterLogoWithText.svg deleted file mode 100644 index a982add98..000000000 --- a/web/src/assets/svg/BusterLogoWithText.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/web/src/assets/svg/BusterLogoWithText.tsx b/web/src/assets/svg/BusterLogoWithText.tsx index 0a6b0ca04..c4ea9929a 100644 --- a/web/src/assets/svg/BusterLogoWithText.tsx +++ b/web/src/assets/svg/BusterLogoWithText.tsx @@ -1,30 +1,27 @@ -export const BusterLogoWithText = ({ className }: { className?: string }) => { +import React from 'react'; + +export const BusterLogoWithText: React.FC<{ + onClick?: () => void; + className?: string; + style?: React.CSSProperties; + color?: string; +}> = ({ color = 'currentColor', ...props }) => { return ( - - - ); diff --git a/web/src/assets/svg/BusterLogoWithTextBW.tsx b/web/src/assets/svg/BusterLogoWithTextBW.tsx deleted file mode 100644 index d51256e67..000000000 --- a/web/src/assets/svg/BusterLogoWithTextBW.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; - -export const BusterLogoWithTextBW: React.FC<{ - className?: string; -}> = ({ className = '' }) => { - return ( - - - - - ); -}; diff --git a/web/src/assets/svg/BusterLogos.stories.tsx b/web/src/assets/svg/BusterLogos.stories.tsx new file mode 100644 index 000000000..af518f430 --- /dev/null +++ b/web/src/assets/svg/BusterLogos.stories.tsx @@ -0,0 +1,34 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { BusterLogo } from './BusterLogo'; +import { BusterLogoWithText } from './BusterLogoWithText'; + +const meta: Meta = { + title: 'Base/Logos', + tags: ['autodocs'], + argTypes: { + className: { control: 'text' } + } +}; + +export default meta; +type Story = StoryObj; + +export const DefaultBusterLogo: Story = { + render: (args) => +}; + +type BusterLogoNewStory = StoryObj; + +export const DefaultBusterLogoWithText: BusterLogoNewStory = { + render: (args) => , + args: { + color: 'currentColor' + } +}; + +export const CustomColorBusterLogoWithText: BusterLogoNewStory = { + render: (args) => , + args: { + color: '#FF0000' + } +}; diff --git a/web/src/components/ui/buttons/Button.tsx b/web/src/components/ui/buttons/Button.tsx index bc15f97c3..229755d52 100644 --- a/web/src/components/ui/buttons/Button.tsx +++ b/web/src/components/ui/buttons/Button.tsx @@ -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, diff --git a/web/src/components/ui/card/InfoCard.stories.tsx b/web/src/components/ui/card/InfoCard.stories.tsx new file mode 100644 index 000000000..17515e1f5 --- /dev/null +++ b/web/src/components/ui/card/InfoCard.stories.tsx @@ -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 = { + title: 'Base/InfoCard', + component: InfoCard, + tags: ['autodocs'], + args: { + title: faker.lorem.sentence(), + description: faker.lorem.paragraph(), + icon: , + 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; + +export const Default: Story = { + args: { + title: 'Notifications', + description: 'You have 3 unread messages', + icon: , + iconPosition: 'center' + } +}; + +export const TopIcon: Story = { + args: { + title: 'System Status', + description: 'All systems are operational', + icon: , + iconPosition: 'top' + } +}; + +export const BottomIcon: Story = { + args: { + title: 'Updates Available', + description: 'New version 2.0 is ready to install', + icon: , + iconPosition: 'bottom' + } +}; + +export const AbsoluteTopIcon: Story = { + args: { + title: 'Important Notice', + description: 'Please review your account settings', + icon: , + iconPosition: 'absolute-top' + } +}; + +export const NoIcon: Story = { + args: { + title: 'Simple Card', + description: 'A card without an icon', + icon: null + } +}; diff --git a/web/src/components/ui/card/InfoCard.tsx b/web/src/components/ui/card/InfoCard.tsx new file mode 100644 index 000000000..f5ca49faa --- /dev/null +++ b/web/src/components/ui/card/InfoCard.tsx @@ -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 { + variant?: VariantProps['variant']; + size?: VariantProps['size']; + title: string; + description: string; + icon: React.ReactNode; + iconPosition?: 'top' | 'center' | 'bottom' | 'absolute-top'; + onClick?: () => void; + selected?: boolean; +} + +export const InfoCard: React.FC = React.memo( + ({ + size = 'default', + variant = 'default', + title, + description, + icon, + iconPosition = 'center', + className, + onClick, + selected = false, + ...props + }) => { + return ( +
+
+

{title}

+

{description}

+
+ {icon && ( +
+ {icon} +
+ )} +
+ ); + } +); + +InfoCard.displayName = 'InfoCard'; diff --git a/web/src/components/ui/icons/customIcons/BuserLogoBW.svg b/web/src/components/ui/icons/customIcons/BuserLogoBW.svg deleted file mode 100644 index 5293cbc8c..000000000 --- a/web/src/components/ui/icons/customIcons/BuserLogoBW.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/web/src/controllers/AppSidebar/AppSidebarTopItems.tsx b/web/src/controllers/AppSidebar/AppSidebarTopItems.tsx index 4c37504b3..c3ee47e1a 100644 --- a/web/src/controllers/AppSidebar/AppSidebarTopItems.tsx +++ b/web/src/controllers/AppSidebar/AppSidebarTopItems.tsx @@ -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'; diff --git a/web/src/lib/imageGeneration.tsx b/web/src/lib/imageGeneration.tsx index 815b7a6fa..5dfdab06c 100644 --- a/web/src/lib/imageGeneration.tsx +++ b/web/src/lib/imageGeneration.tsx @@ -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))' }}> - + <>
); diff --git a/web/src/styles/tailwind.css b/web/src/styles/tailwind.css index 34f499d1c..946889108 100644 --- a/web/src/styles/tailwind.css +++ b/web/src/styles/tailwind.css @@ -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;