Skip to content

Commit

Permalink
feat(components): add ToggleButtonGroup (#1496)
Browse files Browse the repository at this point in the history
  • Loading branch information
Niznikr authored Dec 5, 2024
1 parent 0b27100 commit cd85be1
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/eleven-toys-run.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@launchpad-ui/components": patch
---

Add `ToggleButtonGroup`
17 changes: 17 additions & 0 deletions packages/components/__tests__/ToggleButtonGroup.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { describe, expect, it } from 'vitest';

import { render, screen } from '../../../test/utils';
import { ToggleButton, ToggleButtonGroup } from '../src';

describe('ToggleButtonGroup', () => {
it('renders', () => {
render(
<ToggleButtonGroup>
<ToggleButton id="first">First</ToggleButton>
<ToggleButton id="second">Second</ToggleButton>
<ToggleButton id="third">Third</ToggleButton>
</ToggleButtonGroup>,
);
expect(screen.getByRole('radiogroup')).toBeVisible();
});
});
35 changes: 35 additions & 0 deletions packages/components/src/ToggleButtonGroup.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { ForwardedRef } from 'react';
import type { ToggleButtonGroupProps } from 'react-aria-components';

import { cva } from 'class-variance-authority';
import { forwardRef } from 'react';
import {
ToggleButtonGroup as AriaToggleButtonGroup,
composeRenderProps,
} from 'react-aria-components';

import styles from './styles/ToggleButtonGroup.module.css';

const group = cva(styles.group);

const _ToggleButtonGroup = (props: ToggleButtonGroupProps, ref: ForwardedRef<HTMLDivElement>) => {
return (
<AriaToggleButtonGroup
{...props}
ref={ref}
className={composeRenderProps(props.className, (className, renderProps) =>
group({ ...renderProps, className }),
)}
/>
);
};

/**
* A toggle button group allows a user to toggle multiple options, with single or multiple selection.
*
* https://react-spectrum.adobe.com/react-aria/ToggleButtonGroup.html
*/
const ToggleButtonGroup = forwardRef(_ToggleButtonGroup);

export { ToggleButtonGroup };
export type { ToggleButtonGroupProps };
2 changes: 2 additions & 0 deletions packages/components/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ export type { TextAreaProps } from './TextArea';
export type { TextFieldProps } from './TextField';
export type { SnackbarValue, ToastOptions, ToastValue } from './Toast';
export type { ToggleButtonProps } from './ToggleButton';
export type { ToggleButtonGroupProps } from './ToggleButtonGroup';
export type { ToggleIconButtonProps } from './ToggleIconButton';
export type { ToolbarProps } from './Toolbar';
export type { TooltipProps, TooltipTriggerProps } from './Tooltip';
Expand Down Expand Up @@ -152,6 +153,7 @@ export { TextArea } from './TextArea';
export { TextField } from './TextField';
export { SnackbarContainer, SnackbarQueue, ToastContainer, ToastQueue } from './Toast';
export { ToggleButton } from './ToggleButton';
export { ToggleButtonGroup } from './ToggleButtonGroup';
export { ToggleIconButton } from './ToggleIconButton';
export { Toolbar } from './Toolbar';
export { Tooltip, TooltipTrigger } from './Tooltip';
Expand Down
9 changes: 9 additions & 0 deletions packages/components/src/styles/ToggleButtonGroup.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.group {
composes: buttonGroup from './base.module.css';
display: flex;

&[data-orientation='vertical'] {
flex-direction: column;
width: fit-content;
}
}
72 changes: 72 additions & 0 deletions packages/components/stories/ToggleButtonGroup.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import type { Meta, StoryObj } from '@storybook/react';

import { ToggleButton, ToggleButtonGroup, ToggleIconButton } from '../src';

const meta: Meta<typeof ToggleButtonGroup> = {
component: ToggleButtonGroup,
// @ts-ignore
subcomponents: { ToggleButton },
title: 'Components/Buttons/ToggleButtonGroup',
parameters: {
status: {
type: import.meta.env.STORYBOOK_PACKAGE_STATUS__COMPONENTS,
},
},
};

export default meta;

type Story = StoryObj<typeof ToggleButtonGroup>;

export const Example: Story = {
args: {
children: (
<>
<ToggleButton id="first">First</ToggleButton>
<ToggleButton id="second">Second</ToggleButton>
<ToggleButton id="third">Third</ToggleButton>
</>
),
defaultSelectedKeys: ['first'],
},
};

export const MultipleSelection: Story = {
args: {
children: (
<>
<ToggleButton id="first">First</ToggleButton>
<ToggleButton id="second">Second</ToggleButton>
<ToggleButton id="third">Third</ToggleButton>
</>
),
selectionMode: 'multiple',
defaultSelectedKeys: ['first', 'second'],
},
};

export const Orientation: Story = {
args: {
children: (
<>
<ToggleButton id="first">First</ToggleButton>
<ToggleButton id="second">Second</ToggleButton>
<ToggleButton id="third">Third</ToggleButton>
</>
),
orientation: 'vertical',
},
};

export const Icons: Story = {
args: {
children: (
<>
<ToggleIconButton id="first" icon="flask" aria-label="flask" />
<ToggleIconButton id="second" icon="flag" aria-label="flag" />
<ToggleIconButton id="third" icon="toggle-on" aria-label="toggle" />
</>
),
orientation: 'vertical',
},
};

0 comments on commit cd85be1

Please sign in to comment.