Skip to content

Commit

Permalink
refactor: use max line prop instead of multiline boolean, add vrts
Browse files Browse the repository at this point in the history
  • Loading branch information
nickofthyme committed Aug 5, 2021
1 parent bdee07e commit d8be979
Show file tree
Hide file tree
Showing 33 changed files with 81 additions and 41 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 13 additions & 7 deletions integration/tests/legend_stories.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('Legend stories', () => {
});
it('should 0 legend buffer', async () => {
await common.expectChartAtUrlToMatchScreenshot(
'http://localhost:9001/?path=/story/legend--legend-spacing-buffer&knob-legend buffer value=0&knob-multiline Legend labels=false',
'http://localhost:9001/?path=/story/legend--legend-spacing-buffer&knob-legend buffer value=0&knob-max legend label lines=1',
);
});
it('should have the same order as nested with no indent even if there are repeated labels', async () => {
Expand All @@ -38,19 +38,19 @@ describe('Legend stories', () => {

it('should correctly render multiline nested legend labels', async () => {
await common.expectChartAtUrlToMatchScreenshot(
'http://localhost:9001/?path=/story/legend--piechart&globals=backgrounds.value:!hex(fff);themes.value:Light&knob-Hide color picker=true&knob-Hide color picker_Legend=true&knob-Inside chart_Legend=true&knob-Legend position=right&knob-Legend position_Legend=right&knob-Multiline_Label options=true&knob-Multiline_Legend=true&knob-Number of series=5&knob-Popover position=leftCenter&knob-Popover position_Legend=leftCenter&knob-Series with long name=3&knob-direction_Legend=vertical&knob-floating columns_Legend=2&knob-hAlign_Legend=right&knob-legend buffer value=80&knob-legend margins=20&knob-long label text_Legend=Non do aliqua veniam dolore ipsum eu aliquip. Culpa in duis amet non velit qui non ullamco sit adipisicing. Ut sunt Lorem mollit exercitation deserunt officia sunt ipsum eu amet.&knob-multiline Legend labels=true&knob-vAlign_Legend=bottom&knob-Partition Layout=sunburst&knob-flatLegend=&knob-showLegendExtra=&knob-legendMaxDepth=2&knob-legendStrategy=key&knob-Multiline=true',
'http://localhost:9001/?path=/story/legend--piechart&globals=backgrounds.value:!hex(fff);themes.value:Light&knob-Hide color picker=true&knob-Hide color picker_Legend=true&knob-Legend position=right&knob-Legend position_Legend=right&knob-max legend label lines=0&knob-Number of series=5&knob-Popover position=leftCenter&knob-Popover position_Legend=leftCenter&knob-Series with long name=3&knob-direction_Legend=vertical&knob-floating columns_Legend=2&knob-hAlign_Legend=right&knob-legend buffer value=80&knob-legend margins=20&knob-long label text_Legend=Non do aliqua veniam dolore ipsum eu aliquip. Culpa in duis amet non velit qui non ullamco sit adipisicing. Ut sunt Lorem mollit exercitation deserunt officia sunt ipsum eu amet.&knob-multiline Legend labels=true&knob-vAlign_Legend=bottom&knob-Partition Layout=sunburst&knob-flatLegend=&knob-showLegendExtra=&knob-legendMaxDepth=2&knob-legendStrategy=key',
);
});

it('should correctly render very long multiline legend labels', async () => {
await common.expectChartAtUrlToMatchScreenshot(
'http://localhost:9001/?path=/story/legend--legend-spacing-buffer&globals=backgrounds.value:transparent;themes.value:Light&knob-Hide color picker=true&knob-Hide color picker_Legend=true&knob-Inside chart_Legend=true&knob-Legend position=right&knob-Legend position_Legend=right&knob-Multiline=true&knob-Multiline_Label options=true&knob-Multiline_Legend=true&knob-Number of series=5&knob-Partition Layout=sunburst&knob-Popover position=leftCenter&knob-Popover position_Legend=leftCenter&knob-Series with long name=3&knob-direction_Legend=vertical&knob-flatLegend=true&knob-floating columns_Legend=2&knob-hAlign_Legend=right&knob-legend buffer value=80&knob-legend margins=20&knob-legendMaxDepth=3&knob-legendStrategy=key&knob-long label text_Legend=Non do aliqua veniam dolore ipsum eu aliquip. Culpa in duis amet non velit qui non ullamco sit adipisicing. Ut sunt Lorem mollit exercitation deserunt officia sunt ipsum eu amet.&knob-multiline Legend labels=true&knob-showLegendExtra=true&knob-use long labels=true&knob-vAlign_Legend=bottom',
'http://localhost:9001/?path=/story/legend--legend-spacing-buffer&globals=backgrounds.value:transparent;themes.value:Light&knob-Hide color picker=true&knob-Hide color picker_Legend=true&knob-Legend position=right&knob-Legend position_Legend=right&knob-Number of series=5&knob-Partition Layout=sunburst&knob-Popover position=leftCenter&knob-Popover position_Legend=leftCenter&knob-Series with long name=3&knob-direction_Legend=vertical&knob-flatLegend=true&knob-floating columns_Legend=2&knob-hAlign_Legend=right&knob-legend buffer value=80&knob-legend margins=20&knob-legendMaxDepth=3&knob-legendStrategy=key&knob-long label text_Legend=Non do aliqua veniam dolore ipsum eu aliquip. Culpa in duis amet non velit qui non ullamco sit adipisicing. Ut sunt Lorem mollit exercitation deserunt officia sunt ipsum eu amet.&knob-max legend label lines=0&knob-showLegendExtra=true&knob-use long labels=true&knob-vAlign_Legend=bottom',
);
});

it('should breakup multiline legend labels with long continous words', async () => {
await common.expectChartAtUrlToMatchScreenshot(
'http://localhost:9001/?path=/story/legend--inside-chart&globals=backgrounds.value:transparent;themes.value:Light&knob-Inside chart_Legend=&knob-Legend position_Legend=right&knob-Multiline_Label options=true&knob-Multiline_Legend=true&knob-Number of series=5&knob-Popover position_Legend=leftCenter&knob-Series with long name=3&knob-direction_Legend=vertical&knob-floating columns_Legend=2&knob-hAlign_Legend=right&knob-long label_Legend=a few separate words then averyongcontinuouswordthatneedstobebrokenup&knob-vAlign_Legend=bottom&knob-multiline label_Legend=true',
'http://localhost:9001/?path=/story/legend--inside-chart&globals=backgrounds.value:transparent;themes.value:Light&knob-Inside chart_Legend=false&knob-Legend position_Legend=right&knob-max label lines_Legend=0&knob-Number of series=5&knob-Popover position_Legend=leftCenter&knob-Series with long name=3&knob-direction_Legend=vertical&knob-floating columns_Legend=2&knob-hAlign_Legend=right&knob-long label_Legend=a few separate words then averyongcontinuouswordthatneedstobebrokenup&knob-vAlign_Legend=bottom',
);
});

Expand Down Expand Up @@ -201,17 +201,23 @@ describe('Legend stories', () => {
await common.expectChartAtUrlToMatchScreenshot(getPositionalUrl(p1, p2, '&globals=themes.value:Dark'));
});

const longLabel =
'Non do aliqua veniam dolore ipsum eu aliquip. Culpa in duis amet non velit qui non ullamco sit adipisicing. Ut sunt Lorem mollit exercitation deserunt officia sunt ipsum eu amet.';

it.each([
[Position.Top, Position.Left],
[Position.Top, Position.Right],
[Position.Bottom, Position.Left],
[Position.Bottom, Position.Right],
])('should correctly display %s %s in multiline mode', async (p1, p2) => {
const longLabel =
'Non do aliqua veniam dolore ipsum eu aliquip. Culpa in duis amet non velit qui non ullamco sit adipisicing. Ut sunt Lorem mollit exercitation deserunt officia sunt ipsum eu amet.';
await common.expectChartAtUrlToMatchScreenshot(
getPositionalUrl(p1, p2, `&knob-max label lines_Legend=0&knob-long label_Legend=${longLabel}`),
);
});

it.each([0, 1, 3])('should correctly truncate multiline labels up to maxLines set to %d', async (maxLines) => {
await common.expectChartAtUrlToMatchScreenshot(
getPositionalUrl(p1, p2, `&knob-multiline label_Legend=true&knob-long label_Legend=${longLabel}`),
`http://localhost:9001/?path=/story/legend--inside-chart&globals=backgrounds.value:transparent;themes.value:Light&knob-Number of series=5&knob-Series with long name=3&knob-Inside chart_Legend=false&knob-floating columns_Legend=2&knob-vAlign_Legend=bottom&knob-hAlign_Legend=right&knob-direction_Legend=vertical&knob-max label lines_Legend=${maxLines}&knob-long label_Legend=${longLabel}`,
);
});
});
Expand Down
17 changes: 11 additions & 6 deletions packages/charts/src/components/legend/_legend_item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -75,15 +75,20 @@ $legendItemHeight: #{$euiFontSizeXS * $euiLineHeight};
align-items: center;
hyphens: auto;

&:not(&--multiline) {
&--singleline {
@include euiTextTruncate;
}

&--clickable {
&:hover {
cursor: pointer;
text-decoration: underline;
}
&--multiline:is(div) { // div to prevent changing to button
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2; // number of lines to show, overridden in element styles
}

&--clickable:hover {
cursor: pointer;
text-decoration: underline;
}
}

Expand Down
41 changes: 30 additions & 11 deletions packages/charts/src/components/legend/label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,60 @@
*/

import classNames from 'classnames';
import React, { MouseEventHandler } from 'react';
import React, { KeyboardEventHandler, MouseEventHandler, useCallback } from 'react';

import { LegendLabelOptions } from '../../utils/themes/theme';

interface LabelProps {
label: string;
isSeriesHidden?: boolean;
isToggleable?: boolean;
onClick?: MouseEventHandler;
options?: LegendLabelOptions;
onToggle?: (negate: boolean) => void;
options: LegendLabelOptions;
}
/**
* Label component used to display text in legend item
* @internal
*/
export function Label({ label, isToggleable, onClick, isSeriesHidden, options }: LabelProps) {
export function Label({ label, isToggleable, onToggle, isSeriesHidden, options }: LabelProps) {
const maxLines = Math.abs(options.maxLines);
const labelClassNames = classNames('echLegendItem__label', {
'echLegendItem__label--clickable': Boolean(onClick),
'echLegendItem__label--multiline': options?.multiline,
'echLegendItem__label--clickable': Boolean(onToggle),
'echLegendItem__label--singleline': maxLines === 1,
'echLegendItem__label--multiline': maxLines > 1,
});

const onClick: MouseEventHandler = useCallback(({ shiftKey }) => onToggle?.(shiftKey), [onToggle]);
const onKeyDown: KeyboardEventHandler = useCallback(
({ key, shiftKey }) => {
if (key === ' ' || key === 'Enter') onToggle?.(shiftKey);
},
[onToggle],
);

const title = options.maxLines > 0 ? label : ''; // full text already visible
const clampStyles = maxLines > 1 ? { WebkitLineClamp: maxLines } : {};

return isToggleable ? (
<button
type="button"
// This div is required to allow multiline text truncation, all ARIA requirements are still met
// https://stackoverflow.com/questions/68673034/webkit-line-clamp-does-not-apply-to-buttons
<div
role="button"
tabIndex={0}
className={labelClassNames}
title={options?.multiline ? '' : label} // full text already visible
title={title}
onClick={onClick}
onKeyDown={onKeyDown}
aria-pressed={isSeriesHidden}
style={clampStyles}
aria-label={
isSeriesHidden ? `${label}; Activate to show series in graph` : `${label}; Activate to hide series in graph`
}
>
{label}
</button>
</div>
) : (
<div className={labelClassNames} title={label} onClick={onClick}>
<div className={labelClassNames} title={label} style={clampStyles}>
{label}
</div>
);
Expand Down
10 changes: 5 additions & 5 deletions packages/charts/src/components/legend/legend_item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export interface LegendItemProps {
positionConfig: LegendPositionConfig;
extraValues: Map<string, LegendItemExtraValues>;
showExtra: boolean;
labelOptions?: LegendLabelOptions;
labelOptions: LegendLabelOptions;
colorPicker?: LegendColorPicker;
action?: LegendAction;
onClick?: LegendItemListener;
Expand Down Expand Up @@ -115,19 +115,19 @@ export class LegendListItem extends Component<LegendItemProps, LegendItemState>
/**
* Returns click function only if toggleable or click listern is provided
*/
handleLabelClick = (legendItemId: SeriesIdentifier[]): MouseEventHandler | undefined => {
onLabelToggle = (legendItemId: SeriesIdentifier[]): ((negate: boolean) => void) | undefined => {
const { item, onClick, toggleDeselectSeriesAction, totalItems } = this.props;
if (totalItems <= 1 || (!item.isToggleable && !onClick)) {
return;
}

return ({ shiftKey }) => {
return (negate) => {
if (onClick) {
onClick(legendItemId);
}

if (item.isToggleable) {
toggleDeselectSeriesAction(legendItemId, shiftKey);
toggleDeselectSeriesAction(legendItemId, negate);
}
};
};
Expand Down Expand Up @@ -215,7 +215,7 @@ export class LegendListItem extends Component<LegendItemProps, LegendItemState>
label={label}
options={labelOptions}
isToggleable={totalItems > 1 && item.isToggleable}
onClick={this.handleLabelClick(seriesIdentifiers)}
onToggle={this.onLabelToggle(seriesIdentifiers)}
isSeriesHidden={isSeriesHidden}
/>
{extra && !isSeriesHidden && renderExtra(extra)}
Expand Down
3 changes: 3 additions & 0 deletions packages/charts/src/utils/themes/dark_theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ export const DARK_THEME: Theme = {
horizontalHeight: 64,
spacingBuffer: 10,
margin: 0,
labelOptions: {
maxLines: 1,
},
},
crosshair: {
band: {
Expand Down
3 changes: 3 additions & 0 deletions packages/charts/src/utils/themes/light_theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ export const LIGHT_THEME: Theme = {
horizontalHeight: 64,
spacingBuffer: 10,
margin: 0,
labelOptions: {
maxLines: 1,
},
},
crosshair: {
band: {
Expand Down
10 changes: 7 additions & 3 deletions packages/charts/src/utils/themes/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,13 @@ export interface BackgroundStyle {
/** @public */
export interface LegendLabelOptions {
/**
* Allows multiline labels
* Sets maxlines allowable before truncating
*
* Setting value to `0` will _never_ truncate the text
*
* @defaultValue 1
*/
multiline: boolean;
maxLines: number;
}

/** @public */
Expand Down Expand Up @@ -237,7 +241,7 @@ export interface LegendStyle {
/**
* Options to control legend labels
*/
labelOptions?: LegendLabelOptions;
labelOptions: LegendLabelOptions;
}
/** @public */
export interface Theme {
Expand Down
4 changes: 2 additions & 2 deletions storybook/stories/legend/10_sunburst.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export const Example = () => {
step: 1,
});
const legendStrategy = select('legendStrategy', LegendStrategy, LegendStrategy.Key as LegendStrategy);
const multiline = boolean('Multiline', false);
const maxLines = number('max legend label lines', 1, { min: 0, step: 1 });

return (
<Chart>
Expand All @@ -51,7 +51,7 @@ export const Example = () => {
legendStrategy={legendStrategy}
legendMaxDepth={legendMaxDepth}
baseTheme={useBaseTheme()}
theme={{ legend: { labelOptions: { multiline } } }}
theme={{ legend: { labelOptions: { maxLines } } }}
/>
<Partition
id="spec_1"
Expand Down
4 changes: 2 additions & 2 deletions storybook/stories/legend/11_legend_actions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
EuiFlexItem,
EuiButtonIcon,
} from '@elastic/eui';
import { boolean } from '@storybook/addon-knobs';
import { boolean, number } from '@storybook/addon-knobs';
import React, { useState } from 'react';

import {
Expand Down Expand Up @@ -164,7 +164,7 @@ const getLabelOptionKnobs = (): LegendLabelOptions => {
const group = 'Label options';

return {
multiline: boolean('Multiline', false, group),
maxLines: number('max label lines', 1, { min: 0, step: 1 }, group),
};
};

Expand Down
4 changes: 2 additions & 2 deletions storybook/stories/legend/12_legend_margins.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import { boolean, number } from '@storybook/addon-knobs';
import { number } from '@storybook/addon-knobs';
import React from 'react';

import { Axis, BarSeries, Chart, Position, ScaleType, Settings } from '@elastic/charts';
Expand All @@ -24,7 +24,7 @@ export const Example = () => (
min: 0,
}),
labelOptions: {
multiline: boolean('multiline Legend labels', true),
maxLines: number('max legend label lines', 2, { min: 0, step: 1 }),
},
},
}}
Expand Down
4 changes: 2 additions & 2 deletions storybook/stories/legend/13_inside_chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const Example = () => {
LayoutDirection.Vertical,
'Legend',
);
const multiline = boolean('multiline label', false, 'Legend');
const maxLines = number('max label lines', 1, { min: 0, step: 1 }, 'Legend');

return (
<Chart>
Expand All @@ -91,7 +91,7 @@ export const Example = () => {
floatingColumns,
}}
theme={{
legend: { labelOptions: { multiline } },
legend: { labelOptions: { maxLines } },
}}
baseTheme={useBaseTheme()}
/>
Expand Down
2 changes: 1 addition & 1 deletion storybook/stories/legend/8_spacing_buffer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const Example = () => {
legend: {
spacingBuffer: number('legend buffer value', 80),
labelOptions: {
multiline: boolean('multiline Legend labels', true),
maxLines: number('max legend label lines', 0, { min: 0, step: 1 }),
},
},
};
Expand Down

0 comments on commit d8be979

Please sign in to comment.