-
Notifications
You must be signed in to change notification settings - Fork 69
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
Split Button - initial concept. Includes Docs update. #1193
Split Button - initial concept. Includes Docs update. #1193
Conversation
@pjfitzgibbons can you attach some screenshots so that we don't have to pull down the PR to confirm visual changes? |
@ashwin-pc updated. I am wondering if the hairline between Primary button and drop-down button needs to be more styled? |
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
fcc133d
to
8747ec9
Compare
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
8747ec9
to
b0c9045
Compare
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
@ashwin-pc @canascar @shanilpa Could you please label this with "2.0.0" and "1.x" per the RELEASING.md ? |
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
…ick/href for each option item. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
<OuiButtonIcon | ||
display={iconDisplay} | ||
//@ts-ignore - typedef conflict between ButtonColor, OuiButtonIconColor | ||
// https://github.com/opensearch-project/oui/issues/1196 |
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.
Per conversation w/ @ashwin-pc , we decided the prudent option was to except this and track an issue for the typedef conflict.
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 happens because of
{...propsForDropdownButton} |
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.
@pjfitzgibbons It seems like the click action triggers two independent button animations - 1 on the clicked individual inner button and 1 on the container. Currently it appears the way this split button has been built is using two separate buttons (a Button with a label and a Button with a down arrow icon wrapped in a container that inherits button animation properties. I would opt to remove the animation all together to avoid this unwanted animation behavior - this animation works best when it's a singular button and maybe not so well as a split.
Consider, for example, the way Button groups are treated - button Y animations are eliminated:
https://oui.opensearch.org/1.3/#/navigation/button#button-groups
@kgcreative any thoughts?
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,to add to this, it looks like each individual element has all the chrome of the parent (individual borders, corner radii, etc). That is firmly not in the spirit of this component.The outer border and the animation when you click the button should apply to the outer container. When you click the button, you should get the depress behavior on the whole element. When you click the drop down, there should be no animation. This is definitely a 2.13 follow-up. If I have some time I may do a couple of quick animations to illustrate the difference, but when you look at Carlos' design, the border between the buttons is a single vertical bar, not two left and right borders that come together.
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 have addressed and solved the issues for both animation and hairline.
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.
@joshuali925 Nice catch! @pjfitzgibbons can we fix this then. Just moving the color prop to after propsForDropdownButton
should fix this.
@kgcreative @ashwin-pc @BSFishy @joshuali925 @canascar |
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 think I addressed all of these in my review comments, but just reiterating so I don't forget:
- All of the borders are currently the primary color, making theming color not make much sense
- This is a small nit, and I can totally see how I could be wrong, but I feel like making the divider border between the primary button and the dropdown button smaller makes them less distinct and harder to distinguish. cc @kgcreative on this one
- I feel like string option display either shouldn't be colored or should have more theming. For example, coloring the highlight with the color as well would look a lot better.
{...{ | ||
color: displayColor, | ||
disabled, | ||
fill, | ||
size, | ||
options, | ||
key: `item_${color}_${fill}_${size}`, | ||
}}> |
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.
Why not just set these as regular JSX attributes?
if (filled) return 'Filled'; | ||
if (small) return 'Small'; | ||
|
||
return color; |
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: capital case would be cool
&:hover, | ||
&:active, | ||
&:focus { | ||
-webkit-transform: none; |
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.
Don't we have autoprefixer? @AMoo-Miki
border-top-right-radius: 4px; | ||
border-top-left-radius: 4px; | ||
border-bottom-right-radius: 4px; | ||
border-bottom-left-radius: 4px; |
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.
These should be based off of $ouiSize
: https://oui.opensearch.org/1.3/#/guidelines/sass
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.
Button uses $ouiBorderRadius, so duplicated here.
&:has(.ouiSplitButtonControl--primary:hover:not([class*='isDisabled'])) { | ||
-webkit-transform: translateY(-1px); | ||
transform: translateY(-1px); | ||
} | ||
|
||
&:has(.ouiSplitButtonControl--primary:active:not([class*='isDisabled'])) { | ||
-webkit-transform: translateY(1px); | ||
transform: translateY(1px); | ||
} | ||
|
||
&:has(.ouiSplitButtonControl--primary:focus:not([class*='isDisabled'])) { | ||
animation: ouiButtonActive $ouiAnimSpeedNormal $ouiAnimSlightBounce; | ||
} |
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 my testing, I wasn't able to activate these selectors
|
||
.ouiSplitButtonControl { | ||
|
||
border: 1px solid $ouiColorPrimary; |
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 color should be based off of the color of button that is selected. Otherwise other colors will have a primary border
.ouiSplitButtonControl { | ||
display: block; | ||
} |
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 this is needed right? The element is already div
, so display
should be block
by default
href={option.href} | ||
target={option.target} | ||
onClick={option.onClick} |
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.
The option click actions shouldn't occur here. They should be put on the primary button so I am able to select whichever button I want to use and perform the operation in 2 separate steps.
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.
Spoke offline. This is fine since the action thats performed on click is determined by the parent component, both switching options and immediately executing the option are possible like this.
In discussion with @ashwin-pc, we decided that providing the base functionality is the preferred solution. The user, through use of item's onClick() and the SplitButton text content ({children}), the GH experience can be achieved. Is this satisfactory? |
@kgcreative and I just had a conversation going over all of these points. I'll try to summarize what we found:
|
@BSFishy that was the original design that @pjfitzgibbons created. I asked him to remove it because both types of interactions could be achieved with just one flow because the parent component could anyways decide how to render the component when the options are clicked. I prefer this to using a prop to toggle between the two interaction patterns because it makes the component props cleaner and more easy to maintain. Adding an extra prop when the same functionality can be achieved with the existing props feels unnecessary imo. Also this way its a two way door decision. If we dont like it and feel the need for that prop, we can always add it in the future in a minor release. It does not need to block the release of this component |
@ashwin-pc I need you to see above and agree on the direction. You are a reviewer and if you disagree then we need to discuss further. cc: @kgcreative @BSFishy |
This may be more of a documentation issue than a component design issue. If we don't need a prop for click + switch vs switch, then we should just show the variations as examples. |
I can definitely put examples on the doc. I had that in mind, and if it's
a critical go/nogo component of the feature, then I'll put it in there.
Meanwhile I'm addressing the technical findings.
Thanks and Kindest Regards,
Peter Fitzgibbons
…On Mon, Jan 8, 2024 at 11:39 AM Kevin Garcia ***@***.***> wrote:
@ashwin-pc <https://github.com/ashwin-pc> I need you to see above and
agree on the direction. You are a reviewer and if you disagree then we need
to discuss further.
cc: @kgcreative <https://github.com/kgcreative> @BSFishy
<https://github.com/BSFishy>
This may be more of a documentation issue than a component design option.
If we don't need a prop for click + switch vs switch, then we should just
show the variations as examples.
—
Reply to this email directly, view it on GitHub
<#1193 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAACYNRUSOREXKCLYSDLM53YNRDPRAVCNFSM6AAAAABBDUVJOWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOBRG4YTAMZVGI>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Yeah, I just got aligned with Ashwin. So we want both scenarios to be documented: action on click and change on click. Here is the change on click example I was thinking of: export default () => {
const [selectedIndex, setSelectedIndex] = useState(0);
const options = [
{
display: (
<Fragment>
<strong>Option one</strong>
<OuiText disabled size="s" color="subdued">
Has a short description giving more detail to the option.
</OuiText>
</Fragment>
),
button: 'Option one',
onClick: () => setSelectedIndex(0),
onButtonClick: () => console.log('Option one clicked'),
},
{
display: (
<Fragment>
<strong>Option two</strong>
<OuiText size="s" color="subdued">
Has a short description giving more detail to the option.
</OuiText>
</Fragment>
),
button: 'Option two',
onClick: () => setSelectedIndex(1),
onButtonClick: () => console.log('Option two clicked'),
},
{
display: 'Just some Text',
button: 'Option three',
onClick: () => setSelectedIndex(2),
onButtonClick: () => console.log('Option three clicked'),
},
];
return (
<OuiSplitButton
options={options}
selectedIndex={selectedIndex}
onClick={options[selectedIndex].onButtonClick}
hasDividers>
{options[selectedIndex].button}
</OuiSplitButton>
);
}; This example somewhat works, but some of the interactions still need to be fixed. (TLDR; we're aligned on the current approach, no more effort needed on that front. Just rounding out the edges. I'll update my review comment to reflect this) |
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 making many of the changes @pjfitzgibbons. Just a few more comments but its looks close to complete.
- There still exists the extra space that i called out in my last review when
selectedIndex
is undefined. cc: @kgcreative, @canascar what do you think? - The key interactions are fine for the initial implementation but i feel like these can be improved. Maybe something we can target for a future release. One thing i did want to highlight for this iteration though is that we arent closing the dropdown when the user tabs out of the dropdown. Can we fix that?
- This has been called out already but I too feel like the border color not matching the behavior of
Button
needs to be fixed.
* @param param1 - options : interval, timeout, message | ||
* @returns void | ||
*/ | ||
// Deprecate/delete after resolution of https://github.com/opensearch-project/oui/issues/1197 |
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 creating this issue :)
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 the tests you have added.
/** | ||
* Optional additional props to send to Primary Button | ||
*/ | ||
propsForPrimaryButton?: OuiButtonProps; | ||
|
||
/** | ||
* Optional additional props to send to Dropdown Button | ||
*/ | ||
propsForDropdownButton?: OuiButtonProps; | ||
|
||
/** | ||
* Optional additional props to send to each Option Item, when | ||
* it is string, rendered with OuiText wrapper | ||
*/ | ||
propsForOptionItems?: OuiTextProps; |
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: Can we name this similar to textProps
for Button
.
/** | |
* Optional additional props to send to Primary Button | |
*/ | |
propsForPrimaryButton?: OuiButtonProps; | |
/** | |
* Optional additional props to send to Dropdown Button | |
*/ | |
propsForDropdownButton?: OuiButtonProps; | |
/** | |
* Optional additional props to send to each Option Item, when | |
* it is string, rendered with OuiText wrapper | |
*/ | |
propsForOptionItems?: OuiTextProps; | |
/** | |
* Optional additional props to send to Primary Button | |
*/ | |
buttonProps?: OuiButtonProps; | |
/** | |
* Optional additional props to send to Dropdown Button | |
*/ | |
dropdownProps?: OuiButtonProps; | |
/** | |
* Optional additional props to send to each Option Item, when | |
* it is string, rendered with OuiText wrapper | |
*/ | |
optionProps?: OuiTextProps; |
href={option.href} | ||
target={option.target} | ||
onClick={option.onClick} |
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.
Spoke offline. This is fine since the action thats performed on click is determined by the parent component, both switching options and immediately executing the option are possible like this.
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Popover styling and keyboard control corrected. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
code cleanup. propagate optional props into their target components recover Change Demo doc. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
0bdb5de
to
5230a3e
Compare
Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com>
* Split Button - initial concept. Includes Docs update. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * WIP SplitButton w/ Popover wrapper and dropdown list Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Style primary control w/ hairline separator Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Hairline Styling -- more Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Setup SplitButton doc Basic/States Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Convert SplitButton to React FC Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Set correct SplitButton doc Basic,States Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * SplitButton tests and updated docs Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Cleanup test and doc lint Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Changelog SplitButton Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Automate CSS Y-axis with buttons in tandem. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * SplitButton handle keyboard control. Unify CSS automation. Allow onClick/href for each option item. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * SplitButton popover correct keyboard interaction Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Border and hairline colors corrected. Popover styling and keyboard control corrected. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * many many nits. code cleanup. propagate optional props into their target components recover Change Demo doc. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * lint fixes and test cleanup. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Copyright Headers Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> --------- Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> (cherry picked from commit eac077e) Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> # Conflicts: # CHANGELOG.md
* Split Button - initial concept. Includes Docs update. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * WIP SplitButton w/ Popover wrapper and dropdown list Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Style primary control w/ hairline separator Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Hairline Styling -- more Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Setup SplitButton doc Basic/States Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Convert SplitButton to React FC Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Set correct SplitButton doc Basic,States Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * SplitButton tests and updated docs Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Cleanup test and doc lint Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Changelog SplitButton Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Automate CSS Y-axis with buttons in tandem. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * SplitButton handle keyboard control. Unify CSS automation. Allow onClick/href for each option item. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * SplitButton popover correct keyboard interaction Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Border and hairline colors corrected. Popover styling and keyboard control corrected. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * many many nits. code cleanup. propagate optional props into their target components recover Change Demo doc. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * lint fixes and test cleanup. Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> * Copyright Headers Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> --------- Signed-off-by: Peter Fitzgibbons <peter.fitzgibbons@gmail.com> (cherry picked from commit eac077e) Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> # Conflicts: # CHANGELOG.md Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Description
Implement SplitButton component
Screen.Recording.2024-01-08.at.08.55.34.mov
Issues Resolved
Fixes #1187
Check List
yarn lint
yarn test-unit
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.