Skip to content

Commit

Permalink
Add "variant" prop to ButtonGroup component
Browse files Browse the repository at this point in the history
  • Loading branch information
ggdouglas committed Feb 4, 2025
1 parent 4e4af34 commit d2572a0
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 11 deletions.
2 changes: 2 additions & 0 deletions packages/core/src/common/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export const ALERT_WARN_CANCEL_OUTSIDE_CLICK =

export const BUTTON_WARN_MINIMAL = ns + ` <Button> minimal is deprecated. Please use variant="minimal".`;
export const BUTTON_WARN_OUTLINED = ns + ` <Button> outlined is deprecated. Please use variant="outlined".`;
export const BUTTON_GROUP_WARN_MINIMAL = ns + ` <ButtonGroup> minimal is deprecated. Please use variant="minimal".`;
export const BUTTON_GROUP_WARN_OUTLINED = ns + ` <ButtonGroup> outlined is deprecated. Please use variant="outlined".`;

export const HOTKEYS_HOTKEY_CHILDREN = ns + ` <Hotkeys> only accepts <Hotkey> children.`;

Expand Down
19 changes: 17 additions & 2 deletions packages/core/src/components/button/button-group.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,29 @@ visual style, it’s recommended to apply the same `intent` to all buttons withi

@reactCodeExample ButtonGroupIntentExample

@## Variant

Most of **ButtonGroup**'s props are also supported by [**Button**](#core/components/buttons) directly. Setting these props on **ButtonGroup** will apply the same value to all buttons in the group. Note that most modifiers, once enabled on the group, cannot be overridden on child buttons (due to the cascading nature of CSS).

@reactCodeExample ButtonGroupVariantExample

@## Outlined and minimal

Most of **ButtonGroup**'s props are also supported by **Button** directly.
<div class="@ns-callout @ns-intent-warning @ns-icon-warning-sign">
<h5 class="@ns-heading">

Deprecated: use [`variant`](#core/components/buttons.variant) instead

</h5>

</div>

Most of **ButtonGroup**'s props are also supported by [**Button**](#core/components/buttons) directly.
Setting these props on **ButtonGroup** will apply the same value to all buttons
in the group. Note that most modifiers, once enabled on the group, cannot be
overridden on child buttons (due to the cascading nature of CSS).

@reactCodeExample ButtonGroupVariantsExample
@reactCodeExample ButtonGroupOutlinedMinimalExample

@## Flex layout

Expand Down
38 changes: 35 additions & 3 deletions packages/core/src/components/button/buttonGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import classNames from "classnames";
import * as React from "react";

import { type Alignment, Classes } from "../../common";
import { BUTTON_GROUP_WARN_MINIMAL, BUTTON_GROUP_WARN_OUTLINED } from "../../common/errors";
import { DISPLAYNAME_PREFIX, type HTMLDivProps, type Props } from "../../common/props";
import { useValidateProps } from "../../hooks/useValidateProps";

export interface ButtonGroupProps extends Props, HTMLDivProps, React.RefAttributes<HTMLDivElement> {
/**
Expand All @@ -42,6 +44,7 @@ export interface ButtonGroupProps extends Props, HTMLDivProps, React.RefAttribut
/**
* Whether the child buttons should appear with minimal styling.
*
* @deprecated use `variant="minimal"` instead
* @default false
*/
minimal?: boolean;
Expand All @@ -50,9 +53,17 @@ export interface ButtonGroupProps extends Props, HTMLDivProps, React.RefAttribut
* Whether the child buttons should use outlined styles.
*
* @default false
* @deprecated use `variant="outlined"` instead
*/
outlined?: boolean;

/**
* Visual style variant for the child buttons.
*
* @default "solid"
*/
variant?: "minimal" | "outlined" | "solid";

/**
* Whether the child buttons should appear with large styling.
*
Expand All @@ -77,14 +88,35 @@ export interface ButtonGroupProps extends Props, HTMLDivProps, React.RefAttribut
*/
export const ButtonGroup: React.FC<ButtonGroupProps> = React.forwardRef<HTMLDivElement, ButtonGroupProps>(
(props, ref) => {
const { alignText, className, fill, minimal, outlined, large, vertical, ...htmlProps } = props;
// eslint-disable-next-line deprecation/deprecation
const {
alignText,
className,
fill,
minimal,
outlined,
large,
variant = "solid",
vertical,
...htmlProps
} = props;

useValidateProps(() => {
if (minimal != null) {
console.warn(BUTTON_GROUP_WARN_MINIMAL);
}
if (outlined != null) {
console.warn(BUTTON_GROUP_WARN_OUTLINED);
}
}, [minimal, outlined]);

const buttonGroupClasses = classNames(
Classes.BUTTON_GROUP,
{
[Classes.FILL]: fill,
[Classes.LARGE]: large,
[Classes.MINIMAL]: minimal,
[Classes.OUTLINED]: outlined,
[Classes.MINIMAL]: minimal || variant === "minimal",
[Classes.OUTLINED]: outlined || variant === "outlined",
[Classes.VERTICAL]: vertical,
},
Classes.alignmentClass(alignText),
Expand Down
16 changes: 12 additions & 4 deletions packages/core/src/components/button/buttonProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,12 +64,20 @@ export interface ButtonSharedProps extends ActionProps<HTMLElement> {
*/
loading?: boolean;

/** Whether this button should use minimal styles. */
/** @deprecated use `variant="minimal"` instead */
/**
* Whether this button should use minimal styles.
*
* @default false
* @deprecated use `variant="minimal"` instead
*/
minimal?: boolean;

/** Whether this button should use outlined styles. */
/** @deprecated use `variant="outlined"` instead */
/**
* Whether this button should use outlined styles.
*
* @default false
* @deprecated use `variant="outlined"` instead
*/
outlined?: boolean;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,35 @@ export const ButtonGroupIntentExample: React.FC<ExampleProps> = props => {
);
};

export const ButtonGroupVariantsExample: React.FC<ExampleProps> = props => {
export const ButtonGroupVariantExample: React.FC<ExampleProps> = props => {
const code = dedent`
<ButtonGroup variant="outlined">
<Button text="One" />
<Button text="Two" />
<Button text="Three" />
</ButtonGroup>
<ButtonGroup variant="minimal">
<Button text="One" />
<Button text="Two" />
<Button text="Three" />
</ButtonGroup>`;
return (
<CodeExample code={code} {...props}>
<ButtonGroup variant="outlined">
<Button text="One" />
<Button text="Two" />
<Button text="Three" />
</ButtonGroup>
<ButtonGroup variant="minimal">
<Button text="One" />
<Button text="Two" />
<Button text="Three" />
</ButtonGroup>
</CodeExample>
);
};

export const ButtonGroupOutlinedMinimalExample: React.FC<ExampleProps> = props => {
const code = dedent`
<ButtonGroup outlined={true}>
<Button text="One" />
Expand Down
3 changes: 2 additions & 1 deletion packages/docs-app/src/styles/_examples.scss
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@
}
}

#{example("ButtonGroupVariants")},
#{example("ButtonGroupVariant")},
#{example("ButtonGroupOutlinedMinimal")},
#{example("ButtonGroupFlex")} {
.docs-code-example {
flex-direction: column;
Expand Down

0 comments on commit d2572a0

Please sign in to comment.