-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(legend): multiline labels with maxLines option #1285
feat(legend): multiline labels with maxLines option #1285
Conversation
@@ -43,6 +48,7 @@ $legendItemHeight: #{$euiFontSizeXS * $euiLineHeight}; | |||
display: flex; | |||
justify-content: center; | |||
align-items: center; | |||
height: $legendItemHeight; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes the focus size of the action the same as the color dot
}); | ||
|
||
return isToggleable ? ( | ||
<button | ||
type="button" | ||
className={labelClassNames} | ||
title={label} | ||
title={options?.multiline ? '' : label} // full text already visible |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the title is necessary if the full label is visible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could could add another option for
We could add a |
packages/charts/api/charts.api.md
Outdated
@@ -1147,6 +1147,11 @@ export interface LegendColorPickerProps { | |||
// @public (undocumented) | |||
export type LegendItemListener = (series: SeriesIdentifier[]) => void; | |||
|
|||
// @public (undocumented) | |||
export interface LegendLabelOptions { | |||
multiline: boolean; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In partition chart, not for the legend, we use a maxRowCount
property, which might be useful here and be a slightly more uniform API. So, a value of 1 would be the default, and it could be whatever number incl. Infinity if unbounded. While it's not integral to the task, it feels useful to set some sensible row count, and with a maxRowCount
there's no need to break the API in the future, or introduce an additional property, which is only applicable with a multiline: true
value. If a row count is deemed useful, we can preemptively cut down on ifs, ternaries and union types 😸
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah so you are thinking change multiline
option to maxRowCount
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done here d8be979
@@ -45,6 +46,7 @@ export interface LegendItemProps { | |||
positionConfig: LegendPositionConfig; | |||
extraValues: Map<string, LegendItemExtraValues>; | |||
showExtra: boolean; | |||
labelOptions?: LegendLabelOptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: could it be relatively easily solved such that it's only the user facing config API where this is optional, but we can rely on its presence everywhere downstream? Ie. one question mark only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You saying labelOptions: LegendLabelOptions;
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it's an internal type, by this time the reification (augmentation with defaults etc.) of the user input should've happened (if we have shared buy-in of how it often simplifies the implementation and prevents us from possibly handling the non-specified nullish case at multiple places, so also a DRY principle)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done here d8be979
interface LabelProps { | ||
label: string; | ||
isSeriesHidden?: boolean; | ||
isToggleable?: boolean; | ||
onClick?: MouseEventHandler; | ||
options?: LegendLabelOptions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: same here, maybe all such optionality like can go away except for the single public API enty point. I admit to having done plenty of this in code I wrote, more recently thinking that it'd be more economical to reify user input right away, and then avoid having to worry about partials, optionals etc.
We can think about removing question marks from non-@public
types, TS is great for safely allowing such a transition, in the meantime we can consider avoiding them in new code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done here d8be979
const getPositionalUrl = (p1: string, p2: string, others: string = '') => | ||
`http://localhost:9001/?path=/story/legend--inside-chart&knob-vAlign_Legend=${p1}&knob-hAlign_Legend=${p2}${others}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixes knob to align with correct vAlign
and hAlign
properties.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good improvement 🎉 Approving it as there's no blocker.
Optional notes:
- if possible, tweak the CSS such that what's hidden now in case of very long, unbroken words would show up, but no need to invest too much time into it, as the user provided formatter function can detect and apply delimiters eg. at every 10 characters (so the user can solve cornercase need)
- prefer using
maxRowCount
as it's numerical and reuses a name with the like meaning instead of the boolean, even if we initially support1
and some other value eg.Infinity
(if CSS reasonably supports a row count, we can use it now or in some future PR, or JS if really needed in the future) - prefer nullish coalescing of new API properties right at the entrance, so that the entire implementation has a fixed type to work with
Replaced
Screen.Recording.2021-08-05.at.05.28.28.PM.mp4 |
@@ -366,6 +366,7 @@ describe('Interactions', () => { | |||
{ left: 282, top: 80 }, | |||
{ | |||
screenshotSelector: '#story-root', | |||
delay: 1000, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This story was misbehaving, need to look into more later.
@@ -6,12 +6,17 @@ $legendItemHeight: #{$euiFontSizeXS * $euiLineHeight}; | |||
display: flex; | |||
flex-wrap: nowrap; | |||
justify-content: space-between; | |||
align-items: center; | |||
align-items: flex-start; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This caused a slight diff in the inside legends but I think it's acceptable.
// 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={label} | ||
title={title} | ||
onClick={onClick} | ||
onKeyDown={onKeyDown} | ||
aria-pressed={isSeriesHidden} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Converted to button due to this, added all required ARIA props to make it seem like a button.
<div className="colorWrapper"> | ||
<ItemColor | ||
ref={this.colorRef} | ||
color={color} | ||
seriesName={label} | ||
isSeriesHidden={isSeriesHidden} | ||
hasColorPicker={hasColorPicker} | ||
onClick={this.handleColorClick(hasColorPicker)} | ||
pointStyle={pointStyle} | ||
/> | ||
</div> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to prevent jitter when using EuiWrappingPopover
to display the color picker. Before this was picked using :first-of-type
but this is more strict though a little more verbose.
Linting job hung up for 30 minutes for some reason, not cancelable. Ran locally with no errors so gonna merge. |
# [33.2.0](v33.1.0...v33.2.0) (2021-08-06) ### Bug Fixes * heatmap snap domain to interval ([#1253](#1253)) ([b439182](b439182)), closes [#1165](#1165) * hex colors to allow alpha channel ([#1274](#1274)) ([03b4f42](03b4f42)) ### Features * **bullet:** the tooltip shows up around the drawn part of the chart only ([#1278](#1278)) ([a96cbb4](a96cbb4)) * **legend:** multiline labels with maxLines option ([#1285](#1285)) ([e0eb096](e0eb096))
Summary
The
labelOptions.maxLines
property is now available in onTheme.legend
type to set the max number of lines a legend label can take-up before it is truncated.Details
When enabled the multiline mode will trigger items to be align from the top (i.e.
flex-start
). These style changes have no affect on existing single line legend labels.Screen.Recording.2021-08-05.at.11.43.31.AM.mp4
Issues
#1245
Checklist
packages/charts/src/index.ts
(and stories only import from../src
except for test data & storybook)