Skip to content

Commit

Permalink
add both vertical and horizontal orientations for legend
Browse files Browse the repository at this point in the history
  • Loading branch information
annacmc committed Dec 12, 2024
1 parent 2605cba commit c4c7351
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 55 deletions.
48 changes: 28 additions & 20 deletions projects/js-packages/charts/src/components/legend/base-legend.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { LegendOrdinal } from '@visx/legend';
import { scaleOrdinal } from '@visx/scale';
import clsx from 'clsx';
import { FC, useCallback } from 'react';
import { FC } from 'react';
import styles from './legend.module.scss';
import type { LegendProps } from './types';

Expand All @@ -28,33 +28,41 @@ export const BaseLegend: FC< LegendProps > = ( {
range: items.map( item => item.color ),
} );

const handleLabelFormat = useCallback(
( label: string ) => {
const item = items.find( i => i.label === label );
return `${ label }${ item?.value ? ` ${ item.value }` : '' }`;
},
[ items ]
);

return (
<div
className={ clsx( styles.legend, styles[ `legend--${ orientation }` ], className ) }
role="list"
>
<div className={ clsx( styles.legend, className ) } role="list">
<LegendOrdinal
scale={ legendScale }
direction={ orientationToFlexDirection[ orientation ] }
shape="rect"
shapeWidth={ 16 }
shapeHeight={ 16 }
className={ clsx(
styles[ 'legend-items' ],
styles[ 'legend-item' ],
styles[ 'legend-item-swatch' ],
styles[ 'legend-item-label' ]
className={ styles[ 'legend-items' ] }
>
{ labels => (
<div className={ styles[ `legend--${ orientation }` ] }>
{ labels.map( label => (
<div key={ label.text } className={ styles[ 'legend-item' ] }>
<svg width={ 16 } height={ 16 }>
<rect
width={ 16 }
height={ 16 }
fill={ label.value }
className={ styles[ 'legend-item-swatch' ] }
/>
</svg>
<span className={ styles[ 'legend-item-label' ] }>
{ label.text }
{ items.find( item => item.label === label.text )?.value && (
<span className={ styles[ 'legend-item-value' ] }>
{ items.find( item => item.label === label.text )?.value }
</span>
) }
</span>
</div>
) ) }
</div>
) }
labelFormat={ handleLabelFormat }
/>
</LegendOrdinal>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -1,33 +1,26 @@
.legend {
&--vertical {
.legend-items {
flex-direction: column;
}
}

&--horizontal {
.legend-items {
flex-direction: row;
flex-wrap: wrap;
}
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 16px;
}
}

.legend-items {
display: flex;
gap: 1rem;
&--vertical {
display: flex;
flex-direction: column;
gap: 8px;
}
}

.legend-item {
display: flex;
align-items: center;
gap: 0.5rem;
gap: 8px;
font-size: 0.875rem;
}

.legend-item-swatch {
width: 1rem !important;
height: 1rem !important;
border-radius: 2px;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import { BaseLegend } from '../index';
import type { Meta } from '@storybook/react';
import { Meta, StoryObj } from '@storybook/react';
import { BaseLegend } from '../base-legend';

const data = [
{ label: 'Desktop', value: '86%', color: '#3858E9' },
{ label: 'Mobile', value: '52%', color: '#80C8FF' },
];

export default {
const meta: Meta< typeof BaseLegend > = {
title: 'JS Packages/Charts/Legend',
component: BaseLegend,
parameters: {
Expand All @@ -18,18 +13,37 @@ export default {
},
},
},
} satisfies Meta< typeof BaseLegend >;
};

export default meta;
type Story = StoryObj< typeof BaseLegend >;

const mockData = [
{ label: 'Desktop', value: '86%', color: '#3858E9' },
{ label: 'Mobile', value: '52%', color: '#80C8FF' },
];

const Template = args => <BaseLegend { ...args } />;
export const Horizontal: Story = {
args: {
items: mockData,
orientation: 'horizontal',
},
};

export const Default = Template.bind( {} );
Default.args = {
items: data,
orientation: 'horizontal',
export const Vertical: Story = {
args: {
items: mockData,
orientation: 'vertical',
},
};

export const Vertical = Template.bind( {} );
Vertical.args = {
items: data,
orientation: 'vertical',
export const WithLongLabels: Story = {
args: {
items: [
{ label: 'Very Long Desktop Usage', value: '86%', color: '#3858E9' },
{ label: 'Extended Mobile Sessions', value: '52%', color: '#80C8FF' },
{ label: 'Tablet Device Access', value: '35%', color: '#44B556' },
],
orientation: 'horizontal',
},
};

0 comments on commit c4c7351

Please sign in to comment.