Skip to content

Add RcButtonSplit to the component library#17055

Merged
rak-phillip merged 13 commits into
rancher:masterfrom
rak-phillip:task/rc-button-split
Apr 3, 2026
Merged

Add RcButtonSplit to the component library#17055
rak-phillip merged 13 commits into
rancher:masterfrom
rak-phillip:task/rc-button-split

Conversation

@rak-phillip

@rak-phillip rak-phillip commented Mar 27, 2026

Copy link
Copy Markdown
Member

Summary

This adds RcButtonSplit to the component library. This component reflects the design system usage described in the Buttons & Links section.

Occurred changes and/or fixed issues

  • Add RcButtonSplit to the component library
  • Add an items prop to RcButtonSplit
  • Update docs for RcButtonSplit
  • Add left/right icon props

Technical notes summary

The design system co-mingles the button and the dropdown button. I'm keeping these as separate components to reduce the amount of complexity in the base RcButton component. I also opted for the naming convection of RcButtonSplit to keep the naming in close proximity to other button components like RcButton and ButtonDropdown.

Areas or cases that should be tested

We can test adding this to a few areas where we might have resorted to workarounds to ensure that this new component covers all of our existing use cases.

Areas which could experience regressions

NA - This is purely additive at this point.

Screenshot/Video

image image image

Checklist

  • The PR is linked to an issue and the linked issue has a Milestone, or no issue is needed
  • The PR has a Milestone
  • The PR template has been filled out
  • The PR has been self reviewed
  • The PR has a reviewer assigned
  • The PR has automated tests or clear instructions for manual tests and the linked issue has appropriate QA labels, or tests are not needed
  • The PR has reviewed with UX and tested in light and dark mode, or there are no UX changes
  • The PR has been reviewed in terms of Accessibility
  • The PR has considered, and if applicable tested with, the three Global Roles Admin, Standard User and User Base

Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>

@codyrancher codyrancher left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed the code more than I did the styling since I suspect @oboc-sts will do a better job than I will but I can follow up on that if desired.

size?: ButtonSize;
// eslint-disable-next-line vue/require-default-prop
ariaLabel?: string;
placement?: Placement;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a preference so leave it if you prefer otherwise. I think I'd rather just see undefined defaults over eslint disables.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

describe('variant prop', () => {
it.each([
['primary', 'variant-primary'],
['secondary', 'variant-secondary'],

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing multiAction variant from the test and I'm sure it's because this is a dropdown but does that mean we should prevent it from being used as a prop value?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on feedback from Ovi, I think that we will drop link, ghost, and multiAction

@@ -0,0 +1 @@
export { default as RcButtonSplit } from './RcButtonSplit.vue';

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we also want to add an export to pkg/rancher-components/src/index.ts?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, very much so. This has been fixed.

import { ButtonVariant, ButtonSize, IconProps } from '@components/RcButton/types';
import type { Placement } from 'floating-vue';

withDefaults(defineProps<{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want a disabled prop?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think this is important. Fixed


<template #dropdownCollection>
<RcDropdownItem
v-for="(label, id) in items"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because items is a Record<string, string> we may end up with some cases with unexpected orderings.

Image

I think we may want to provide an arrays of objects that adhered to the string -> string interface.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's a good catch! Fixed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're going to want to fix the overflow in storybook.

Image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll see what we can do to maybe resize the canvas in storybook. Otherwise, I don't think we will be in control of the overflow.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be fixed now.. let me know what you think

:deep(.rc-button-split-trigger.variant-primary),
:deep(.rc-button-split-trigger.variant-secondary),
:deep(.rc-button-split-trigger.variant-tertiary) {
border-left: 1px solid rgba(255, 255, 255, 0.3);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tertiary I see the separator in the dark theme but not the light.

Image Image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll sync with Ovi to better understand how we might want to handle tertiary buttons


<template>
<RcDropdown
:aria-label="ariaLabel"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ariaLabel is forwarded to RcDropdown which labels the dropdown menu.

Do we want to label the group with a role and aria-label.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we might want 3 potential labels for this component:

  1. Rename this aria label for the dropdown, which is properly applied to the RcDropdown component
  2. Add a label for the primary button - this might be the default ariaLabel prop
  3. Add a label for the trigger

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@oboc-sts oboc-sts left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good @rak-phillip 💪

Based on the static screenshots alone, I only have 2+1 concerns:

  1. Styling wise, the text line-height used on the main button seems to push the label of the button down a bit (it's not optically align to middle)
  2. We should only support the "split" variant for primary, secondary and maybe (maybe) tertiary, not for all button types (link and ghost should definitely NOT support this). Let's talk about the tertiary offline - I need to better understand where we're using it right now to assess it's usefulness in having the new split variant.
  3. Actions popover alignment. Right now, it seems that we only support aligning the actions popover to the left of the split button - this works nicely for actions with really short names (shorter than the action label used on the main button). But, if the actions in the popover are longer... we'd want to consider aligning the popover to the RHS of the split button to ease the scanning effort. However, this would have to the into account the "bouncing off" the screen edge. So it's a bit more complex than it appears. As a compromise, we can leave this improvement for the next iteration of the component.

Wdyt?

Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
@codyrancher codyrancher self-requested a review April 3, 2026 13:45
codyrancher
codyrancher previously approved these changes Apr 3, 2026

@codyrancher codyrancher left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good from my perspective.

Signed-off-by: Phillip Rak <rak.phillip@gmail.com>
@rak-phillip rak-phillip merged commit 4497338 into rancher:master Apr 3, 2026
66 of 68 checks passed
@rak-phillip rak-phillip deleted the task/rc-button-split branch April 3, 2026 22:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants