mirror of https://github.com/buster-so/buster.git
overflow story
This commit is contained in:
parent
e460fa86f6
commit
4b4ba2e21e
|
@ -1,2 +1 @@
|
|||
export * from './ItemContainer';
|
||||
export * from './CodeCard';
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import { OverflowButton } from './OverflowContainer';
|
||||
import { ChartType } from '../interfaces';
|
||||
|
||||
const meta = {
|
||||
title: 'Base/Charts/OverflowButton',
|
||||
component: OverflowButton,
|
||||
parameters: {
|
||||
layout: 'centered'
|
||||
},
|
||||
tags: ['autodocs']
|
||||
} satisfies Meta<typeof OverflowButton>;
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
const mockLegendItems = [
|
||||
{
|
||||
id: '1',
|
||||
color: '#FF5733',
|
||||
inactive: false,
|
||||
type: ChartType.Line,
|
||||
formattedName: 'Series A',
|
||||
serieName: 'series-a'
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
color: '#33FF57',
|
||||
inactive: false,
|
||||
type: ChartType.Line,
|
||||
formattedName: 'Series B',
|
||||
serieName: 'series-b'
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
color: '#3357FF',
|
||||
inactive: true,
|
||||
type: ChartType.Line,
|
||||
formattedName: 'Inactive Series C',
|
||||
serieName: 'series-c'
|
||||
}
|
||||
];
|
||||
|
||||
export const Default: Story = {
|
||||
args: {
|
||||
legendItems: mockLegendItems,
|
||||
onClickItem: (item) => console.log('Clicked:', item),
|
||||
onFocusClick: (item) => console.log('Focused:', item)
|
||||
}
|
||||
};
|
||||
|
||||
export const WithInactiveItems: Story = {
|
||||
args: {
|
||||
legendItems: mockLegendItems.map((item) => ({ ...item, inactive: true }))
|
||||
}
|
||||
};
|
||||
|
||||
export const WithManyItems: Story = {
|
||||
args: {
|
||||
legendItems: Array.from({ length: 10 }, (_, i) => ({
|
||||
id: `${i + 1}`,
|
||||
color: `hsl(${(i * 36) % 360}, 70%, 50%)`,
|
||||
inactive: false,
|
||||
type: ChartType.Line,
|
||||
formattedName: `Series ${String.fromCharCode(65 + i)}`,
|
||||
serieName: `series-${String.fromCharCode(97 + i)}`
|
||||
}))
|
||||
}
|
||||
};
|
|
@ -1,9 +1,10 @@
|
|||
import { AppPopover } from '@/components/ui/tooltip';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { Popover } from '@/components/ui/tooltip/Popover';
|
||||
import React from 'react';
|
||||
import { BusterChartLegendItem, BusterChartLegendProps } from './interfaces';
|
||||
import { LegendItem } from './LegendItem';
|
||||
import { Text } from '@/components/ui';
|
||||
import { cn } from '@/lib/classMerge';
|
||||
import { LegendItemDot } from './LegendDot';
|
||||
import { ChartType } from '../interfaces';
|
||||
|
||||
export const OverflowButton: React.FC<{
|
||||
legendItems: BusterChartLegendItem[];
|
||||
|
@ -11,15 +12,11 @@ export const OverflowButton: React.FC<{
|
|||
onClickItem?: BusterChartLegendProps['onClickItem'];
|
||||
onHoverItem?: BusterChartLegendProps['onHoverItem'];
|
||||
}> = React.memo(({ legendItems, onFocusClick, onClickItem, onHoverItem }) => {
|
||||
const { styles, cx } = useStyles();
|
||||
|
||||
return (
|
||||
<AppPopover
|
||||
placement="bottomRight"
|
||||
mouseEnterDelay={0.75}
|
||||
trigger={'click'}
|
||||
destroyTooltipOnHide
|
||||
className="max-h-[420px] max-w-[265px]! min-w-[200px] overflow-x-hidden overflow-y-auto px-0"
|
||||
<Popover
|
||||
align="end"
|
||||
side="right"
|
||||
className="max-h-[420px] max-w-[265px]! min-w-[200px] overflow-x-hidden overflow-y-auto px-0 py-1"
|
||||
content={
|
||||
<div className="flex flex-col space-y-1 p-0.5">
|
||||
{legendItems.map((item) => {
|
||||
|
@ -35,66 +32,15 @@ export const OverflowButton: React.FC<{
|
|||
})}
|
||||
</div>
|
||||
}>
|
||||
<div className={cx('flex items-center space-x-1.5', styles.overflowItemContainer)}>
|
||||
<div className={cx(styles.dot, styles.overflowDot, 'flex')} />
|
||||
<Text size="sm" className="text-nowrap select-none">
|
||||
Next {legendItems.length}
|
||||
</Text>
|
||||
<div
|
||||
className={cn(
|
||||
'flex h-[24px] cursor-pointer items-center space-x-1.5 rounded-sm px-2 py-1',
|
||||
'hover:bg-item-hover'
|
||||
)}>
|
||||
<LegendItemDot type={ChartType.Bar} color={undefined} inactive={true} />
|
||||
<span className="text-sm text-nowrap select-none">Next {legendItems.length}</span>
|
||||
</div>
|
||||
</AppPopover>
|
||||
</Popover>
|
||||
);
|
||||
});
|
||||
OverflowButton.displayName = 'OverflowButton';
|
||||
|
||||
const useStyles = createStyles(({ token, css }) => {
|
||||
return {
|
||||
dot: css`
|
||||
background: ${token.colorBgContainerDisabled};
|
||||
width: 18px;
|
||||
min-width: 18px;
|
||||
height: 12px;
|
||||
border-radius: 4px;
|
||||
|
||||
&.group {
|
||||
&:hover {
|
||||
&.focus-item {
|
||||
background-color: ${token.colorBgElevated} !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
|
||||
overflowItemContainer: css`
|
||||
cursor: pointer;
|
||||
padding: 1px 8px;
|
||||
border-radius: 4px;
|
||||
border: 0px solid ${token.colorBorder};
|
||||
// background: ${token.colorBgBase};
|
||||
|
||||
&:hover {
|
||||
background: ${token.controlItemBgHover};
|
||||
}
|
||||
`,
|
||||
overflowDot: css`
|
||||
background: ${token.colorBorder};
|
||||
`,
|
||||
overflowItem: css`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
padding: 3px 5px;
|
||||
border-radius: 4px;
|
||||
&:hover {
|
||||
background: ${token.controlItemBgHover};
|
||||
}
|
||||
&.inactive {
|
||||
border-color: ${token.colorBgContainerDisabled};
|
||||
|
||||
.dot {
|
||||
background: ${token.colorBgContainerDisabled};
|
||||
}
|
||||
}
|
||||
`
|
||||
};
|
||||
});
|
||||
|
|
|
@ -23,12 +23,11 @@ const PopoverContent = React.forwardRef<
|
|||
className={cn(
|
||||
'bg-popover text-popover-foreground',
|
||||
'w-fit rounded border shadow outline-none',
|
||||
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50',
|
||||
className
|
||||
'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50'
|
||||
)}
|
||||
{...props}>
|
||||
{headerContent && <>{headerContent}</>}
|
||||
<div className="p-2.5"> {children}</div>
|
||||
<div className={cn('p-2.5', className)}>{children}</div>
|
||||
</PopoverPrimitive.Content>
|
||||
</PopoverPrimitive.Portal>
|
||||
));
|
||||
|
|
Loading…
Reference in New Issue