diff --git a/src/components/Toggle/README.md b/src/components/Toggle/README.md index 9cffe0a..3d59e07 100644 --- a/src/components/Toggle/README.md +++ b/src/components/Toggle/README.md @@ -27,6 +27,13 @@ import { BBBToggle } from 'bbb-ui-components-react'; ``` +### Full-width toggle with the label at the start and the switch at the end +```jsx +import { BBBToggle } from 'bbb-ui-components-react'; + + +``` + ### Toggle with label and helper text on the top ```jsx import { BBBToggle } from 'bbb-ui-components-react'; @@ -41,6 +48,7 @@ import { BBBToggle } from 'bbb-ui-components-react'; | `label` | `string` | | The main label text displayed next to the toggle. | | `helperText` | `string` | | The helper text displayed below the label. | | `textPosition` | `keyof typeof TEXT_POSITIONS` | `'right'` | The position of the text labels relative to the toggle switch. | +| `fullWidth` | `boolean` | `false` | If `true`, the toggle stretches to its container, putting the text and the switch at opposite ends. Only used with `textPosition` `'left'` (text at the start) or `'right'` (text at the end). | | `disabled` | `boolean` | `false` | If `true`, the toggle will be disabled and unresponsive. | | `onChange` | `(event: React.ChangeEvent, checked: boolean) => void` | | Callback function that is fired when the toggle state changes. | | `ariaLabel` | `string` | | The accessible name for the toggle. | diff --git a/src/components/Toggle/component.stories.tsx b/src/components/Toggle/component.stories.tsx index aecdce5..2f32c4e 100644 --- a/src/components/Toggle/component.stories.tsx +++ b/src/components/Toggle/component.stories.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import BBBToggle from './component'; import { TEXT_POSITIONS_VALUES, DEFAULT_TEXT_POSITION } from './constants'; @@ -13,6 +14,11 @@ const meta = { description: 'Position of label/helper relative to the toggle.', table: { defaultValue: { summary: `${DEFAULT_TEXT_POSITION}` } }, }, + fullWidth: { + control: 'boolean', + description: `Stretches the row to its container, putting the text and the switch at opposite ends. Only used with textPosition 'left' or 'right'.`, + table: { defaultValue: { summary: 'false' } }, + }, label: { control: 'text', description: 'Main label text displayed next to the toggle.', @@ -43,3 +49,22 @@ type Story = StoryObj; export const Default: Story = { args: { label: 'Enable feature' } }; /** Adds helper text below the label, with the label/helper positioned to the right of the toggle. */ export const WithHelper: Story = { args: { label: 'Enable', helperText: 'Recommended', textPosition: 'right' } }; +/** Shows a `fullWidth` toggle in a settings row: label and helper text at the start, switch at the end. */ +export const FullWidth: Story = { + args: { + label: 'Join muted', + helperText: 'Joining users are muted by default', + textPosition: 'left', + fullWidth: true, + }, + render: (args) => ( +
+ +
+ ), +}; +/** Shows a `fullWidth` toggle with the text on the right: switch at the start, label and helper text at the end. */ +export const FullWidthTextRight: Story = { + ...FullWidth, + args: { ...FullWidth.args, textPosition: 'right' }, +}; diff --git a/src/components/Toggle/component.tsx b/src/components/Toggle/component.tsx index ae7afb7..21f7899 100644 --- a/src/components/Toggle/component.tsx +++ b/src/components/Toggle/component.tsx @@ -2,7 +2,7 @@ import React, { JSX, useId } from 'react'; import { SwitchOwnerState } from '@mui/material'; import { ToggleProps } from './types'; import * as Styled from './styles'; -import { DEFAULT_TEXT_POSITION } from './constants'; +import { DEFAULT_TEXT_POSITION, TEXT_POSITIONS } from './constants'; /** * A customizable Toggle switch component. @@ -15,6 +15,7 @@ function Toggle ({ label, helperText, textPosition = DEFAULT_TEXT_POSITION, + fullWidth = false, onChange, ariaLabel, ariaLabelledBy, @@ -27,6 +28,7 @@ function Toggle ({ const id = providedId ?? generatedUniqueId; const labelId = label ? `${id}-label` : undefined; const helperTextId = helperText ? `${id}-helper` : undefined; + const isFullWidth = fullWidth && (textPosition === TEXT_POSITIONS.LEFT || textPosition === TEXT_POSITIONS.RIGHT); const ariaLabelledByValue = ariaLabel ? undefined : ariaLabelledBy || labelId; // Without a name source, the