-
Notifications
You must be signed in to change notification settings - Fork 862
[EuiKeyPadMenuItem] Added checkable option & style updates
#4950
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
Conversation
…d a11y props/elements
Also added a helper mixin for `euiAnimationsAllowed`
|
Preview documentation changes for this PR: https://eui.elastic.co/pr_4950/ |
checkable optioncheckable option & style updates
| // @ts-ignore HELP! | ||
| <Element |
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.
@chandlerprall Since you self-assigned... 😉
I get this error when I remove this ignore:
Type '{ children: Element; ref: ((instance: HTMLAnchorElement | null) => void) | RefObject<HTMLAnchorElement> | ((instance: HTMLButtonElement | null) => void) | RefObject<...> | null | undefined; ... 252 more ...; onTransitionEndCapture?: ((event: TransitionEvent<...>) => void) | undefined; }' is not assignable to type 'IntrinsicAttributes'.
Property 'children' does not exist on type 'IntrinsicAttributes'.
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've pushed a change to help address this. There's still a fallback to as Ref<any> but I don't think it's worth trying to completely satisfy TS there.
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 your change got pushed
| .euiKeyPadMenuItem { | ||
| @include euiFont; /* 1 */ | ||
| // Disable indentation for transition legibility | ||
| // sass-lint:disable-block indentation | ||
| display: block; | ||
| padding: $euiSizeXS; |
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.
FYI: I moved all these item styles to their own file.
|
Preview documentation changes for this PR: https://eui.elastic.co/pr_4950/ |
|
Preview documentation changes for this PR: https://eui.elastic.co/pr_4950/ |
| /** | ||
| * Renders the the group as a `fieldset` with a `legend` to label the items. | ||
| */ | ||
| legend?: ReactNode; |
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.
Thoughts on moving checkable up to here and making legend required if checkable='multi'?
- I think it would seem weird if some of the items in a single menu are radio inputs and others checkable
- A radiogroup should always have a legend
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 I tried that but it doesn't work very well the way we make users manually supply each item vs passing in an object. Mainly the problem lies in the complexity of TS and knowing if the iterative child IS an EuiKeyPadMenuItem or not and can then accept the checkable prop as a pass-through.
Not to say it's not possible, just beyond what I can do for now. You are more than happy to take a stab at it.
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.
Not sure I'll get to it right now but will keep this in the queue.
Another option that would be easier is to require checkable in both places. It doesn't have to do much right now (even just to help with the legend bit right now seems good enough) but will also prevent a breaking change in the future when/if we get to the point that we can remove it from each item within.
It's a little duplicative but helps the upgrade path in the future of where we might want this to go.
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.
Oh, could use CSS to "block" passing in children with the wrong checkable type if we wanted to. Something like adding an obnoxious red border around mismatched items if they don't match the container.
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.
Well, I actually tested what happens is a legend is provided but the items aren't checkable, just <button>s and the SR does provide the legend as a grouping title which I thought was a plus outside of requiring it only if the items are checkable.
| return ( | ||
| return legend ? ( | ||
| <fieldset className={classes} {...rest}> | ||
| <EuiFormLabel type="legend">{legend}</EuiFormLabel> |
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 can see folks avoiding adding a legend because they don't like how it's visually presented.
Should we add the ability to visibly hide the <legend> and/or to supply an aria-label/aria-labelledby to the <fieldset> instead to give that visual flexibility or do we want to enforce a consistent style here?
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.
What approach would you like to see for that? I'd like to stay away from just a boolean isLegendVisible type of prop if possible because it can be misunderstood.
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.
🤔 It's hard/low-value if checkable isn't on the KeyPadMeny (because we shouldn't force a legend if it's not checkable=multi)...
But if it is, I don't have a specific approach in mind. The isLegendVisisble flag is probably what I would have reached for first. Why don't you like it?
Another option is to have two props: legend and ariaLegend (where ariaLegend could also be called screenReaderLegend, visuallyHiddenLegend, etc)
The Charts team has basically taken the aria-* prefix to mean anything screen reader 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.
I like that approach of using ariaProp names to indicate visibility. I worry that it could confuse consumers that it is a real aria- attribute, but probably not a big deal. We can comment as such.
I don't "like" isLegendVisible, because boolean props tend not to be scalable. It's fine for very true booleans like isDisabled, but we don't know in the future what other legend options may be provided. I'll think on a solution.
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.
Ok I updated this to where EuiKeyPadMenu now accepts a singular checkable prop which can be either:
true: Just renders the<fieldset>and requires consumers to still pass in their own labelling via any method they like{ legend | ariaLegend }: WhereariaLegendis just a string applied toarial-labelof thefieldset
They can further customize the <legend> with legendProps
chandlerprall
left a comment
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.
LGTM, pulled & tested functionality & TypeScript configuration locally; pushed a TS change; have one small recommendation for documenting isSelected
| // @ts-ignore HELP! | ||
| <Element |
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've pushed a change to help address this. There's still a fallback to as Ref<any> but I don't think it's worth trying to completely satisfy TS there.
elizabetdev
left a comment
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.
LGTM! 🎉
Tested in Chrome, Safari, Edge, and Firefox. I also looked at the code. 👍🏽
|
Preview documentation changes for this PR: https://eui.elastic.co/pr_4950/ |
|
Preview documentation changes for this PR: https://eui.elastic.co/pr_4950/ |
myasonik
left a comment
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.
Thanks for the changes - looks good!
I'm taking a look at the typescript issue right now, hopefully I can clobber something together.
| type EuiKeyPadMenuItemPropsForAnchor = PropsForAnchor< | ||
| EuiKeyPadMenuItemCommonProps, | ||
| { | ||
| buttonRef?: Ref<HTMLAnchorElement>; |
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.
Thoughts on changing this (throughout the file) to itemRef? buttonRef seems confusing when it can also be an anchor...
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.
Do you think it's a necessary breaking change?
|
@thompsongl Maybe you can take a pass at fixing the TS issue? I'm not getting anywhere 😕 Otherwise we can wait till Chandler's back |
Yes, there is no rush on this PR at all. |
I arrived at what I assume is pretty much the same place as Chandler. Changes pushed. |
|
Preview documentation changes for this PR: https://eui.elastic.co/pr_4950/ |
|
Preview documentation changes for this PR: https://eui.elastic.co/pr_4950/ |
|
Thanks all for the help and reviews! |
Style updates
Before, both the default and Amsterdam themes had the same styling: a simple bordered-on-hover-only item.
Now, the Amsterdam version is more aligned to the designs from Figma and I've added an
isSelectedprop for indicating current items. I also increased the contrast of the text as thesubduedcolor was too subdued for such large (possible primary) menu items and when the icons inherit their color.AFTER:
Checkable
Closes #4000
Adds
checkable = 'multi' | 'single'to the EuiKeyPadMenuItem componentWhen
multi, will display as a checkbox and whensinglewill display as a radio (on hover & selected). It changes the consumer's required interaction prop fromonClicktoonChangeand usesisSelectedto chance thecheckedstatus.Adds
checkableprop to EuiKeyPadMenu for wrapping the group as a<fieldset>Originally I thought to just showcase it being wrapped in an EuiFormRow, but it comes with too much baggage. Therefore, it just allows consumers to pass either:
true: Just renders the<fieldset>and requires consumers to still pass in their own labelling via any method they like{ legend | ariaLegend }: WhereariaLegendis just a string applied toarial-labelof thefieldsetfor a visibly hidden legend. They can further customize the<legend>withlegendProps.This creates the proper accessibility hook-ups.
Other
I also fixed up some styling associated with the beta badge to strictly use the new EuiBetaBadge props.
Checklist