legend item

This commit is contained in:
Nate Kelley 2025-02-26 14:49:35 -07:00
parent 7f8cfe4b4f
commit 9cbb33c569
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
3 changed files with 173 additions and 13 deletions

View File

@ -1,10 +1,10 @@
import React, { useMemo, useEffect, useLayoutEffect } from 'react';
import { BusterChartLegendItem, BusterChartLegendProps } from './interfaces';
import { Text, Title } from '@/components/ui';
import React, { useMemo } from 'react';
import { type BusterChartLegendItem, type BusterChartLegendProps } from './interfaces';
import { createStyles } from 'antd-style';
import { useMemoizedFn } from 'ahooks';
import { LegendItemDot } from './LegendDot';
import { AnimatePresence, motion } from 'framer-motion';
import { cn } from '@/lib/utils';
export const LegendItem: React.FC<{
item: BusterChartLegendItem;
@ -112,12 +112,13 @@ const LegendItemStandard = React.memo(
<AnimatePresence initial={false}>
{hasHeadline && (
<motion.div {...headlineAnimation} className="flex items-center space-x-1.5">
<Title
level={4}
className="leading-none font-semibold!"
type={!inactive ? 'default' : 'tertiary'}>
<span
className={cn(
'text-md leading-none font-semibold!',
!inactive ? 'text-foreground' : 'text-text-secondary'
)}>
{headline?.titleAmount}
</Title>
</span>
</motion.div>
)}
</AnimatePresence>
@ -134,10 +135,11 @@ const LegendItemStandard = React.memo(
inactive={item.inactive}
/>
<Text
size="sm"
className="flex! items-center truncate transition-all duration-100 select-none"
type={!inactive ? 'default' : 'tertiary'}>
<span
className={cn(
'flex! items-center truncate text-base transition-all duration-100 select-none',
!inactive ? 'text-foreground' : 'text-text-secondary'
)}>
<AnimatePresence mode="wait" initial={false}>
{headlinePreText && (
<motion.div
@ -149,7 +151,7 @@ const LegendItemStandard = React.memo(
</AnimatePresence>
{formattedName}
</Text>
</span>
</div>
</motion.div>
);

View File

@ -0,0 +1,152 @@
import type { Meta, StoryObj } from '@storybook/react';
import { LegendItem } from '../LegendItem';
import { ChartType } from '../../interfaces';
const meta = {
title: 'Base/Charts/LegendItem',
component: LegendItem,
parameters: {
layout: 'centered'
},
tags: ['autodocs'],
args: {
item: {
color: '#1677ff',
inactive: false,
type: ChartType.Line,
formattedName: 'Sample Legend',
id: '1',
serieName: 'series1'
}
},
argTypes: {
item: {
control: 'object',
description: 'The legend item configuration'
},
onClickItem: {
action: 'clicked',
description: 'Function called when the legend item is clicked'
},
onFocusItem: {
action: 'focused',
description: 'Function called when the legend item is focused'
},
onHoverItem: {
action: 'hovered',
description: 'Function called when the legend item is hovered'
}
}
} satisfies Meta<typeof LegendItem>;
export default meta;
type Story = StoryObj<typeof LegendItem>;
// Basic legend item
export const Basic: Story = {
args: {
item: {
color: '#1677ff',
inactive: false,
type: ChartType.Line,
formattedName: 'Basic Legend',
id: '1',
serieName: 'series1'
}
}
};
// Inactive legend item
export const Inactive: Story = {
args: {
item: {
color: '#1677ff',
inactive: true,
type: ChartType.Line,
formattedName: 'Inactive Legend',
id: '2',
serieName: 'series2'
}
}
};
// Bar type legend item
export const BarType: Story = {
args: {
item: {
color: '#52c41a',
inactive: false,
type: ChartType.Bar,
formattedName: 'Bar Legend',
id: '3',
serieName: 'series3'
}
}
};
// Scatter type legend item
export const ScatterType: Story = {
args: {
item: {
color: '#722ed1',
inactive: false,
type: ChartType.Scatter,
formattedName: 'Scatter Legend',
id: '4',
serieName: 'series4'
}
}
};
// With headline
export const WithHeadline: Story = {
args: {
item: {
color: '#f5222d',
inactive: false,
type: ChartType.Line,
formattedName: 'Revenue',
id: '5',
serieName: 'series5',
headline: {
type: 'current',
titleAmount: '$50,000'
}
}
}
};
// With average headline
export const WithAverageHeadline: Story = {
args: {
item: {
color: '#fa8c16',
inactive: false,
type: ChartType.Line,
formattedName: 'Monthly Sales',
id: '6',
serieName: 'series6',
headline: {
type: 'average',
titleAmount: '$25,000'
}
}
}
};
// Interactive example with all handlers
export const WithFocusEvent: Story = {
args: {
item: {
color: '#eb2f96',
inactive: false,
type: ChartType.Line,
formattedName: 'Interactive Legend',
id: '7',
serieName: 'series7'
},
onClickItem: (item) => alert(`Clicked: ${item.formattedName}`),
onFocusItem: (item) => alert(`Focused: ${item.formattedName}`)
// onHoverItem: (item, isHover) => alert(`Hover: ${item.formattedName} ${isHover}`)
}
};

View File

@ -91,6 +91,12 @@
--color-ring: var(--color-item-hover);
--color-popover: var(--color-background);
--color-popover-foreground: var(--color-foreground);
/* text color */
--color-text-default: var(--color-foreground);
--color-text-disabled: var(--color-gray-light);
--color-text-secondary: var(--color-gray-dark);
--color-text-tertiary: var(--color-gray-light);
}
@import './tailwindAnimations.css';