Skip to main content
Light Dark System

Segmented Button

<cw-segmented-button> | CwSegmentedButton
Since 1.5 experimental

Segmented buttons let the user select a single option from a set, styled as a joined row of buttons — visually like a button group, but behaves like a radio group (single selection, form-associated value).

Segmented buttons group radio buttons into a single, joined control. Only one segment can be selected at a time, and the selected value is submitted with the form just like a native radio group.

Left Center Right
<cw-segmented-button label="Alignment" value="left">
  <cw-radio-button value="left">Left</cw-radio-button>
  <cw-radio-button value="center">Center</cw-radio-button>
  <cw-radio-button value="right">Right</cw-radio-button>
</cw-segmented-button>
import CwRadioButton from '@cordwainer/cw-elements/dist/react/radio-button';
import CwSegmentedButton from '@cordwainer/cw-elements/dist/react/segmented-button';

const App = () => (
  <CwSegmentedButton label="Alignment" value="left">
    <CwRadioButton value="left">Left</CwRadioButton>
    <CwRadioButton value="center">Center</CwRadioButton>
    <CwRadioButton value="right">Right</CwRadioButton>
  </CwSegmentedButton>
);

Examples

Sizing Options

Set the size attribute to change the size of every segment at once.

Left Center Right
Left Center Right
Left Center Right
<cw-segmented-button size="small" value="left" style="margin-bottom: 1rem;">
  <cw-radio-button value="left">Left</cw-radio-button>
  <cw-radio-button value="center">Center</cw-radio-button>
  <cw-radio-button value="right">Right</cw-radio-button>
</cw-segmented-button>
<br />
<cw-segmented-button size="medium" value="left" style="margin-bottom: 1rem;">
  <cw-radio-button value="left">Left</cw-radio-button>
  <cw-radio-button value="center">Center</cw-radio-button>
  <cw-radio-button value="right">Right</cw-radio-button>
</cw-segmented-button>
<br />
<cw-segmented-button size="large" value="left">
  <cw-radio-button value="left">Left</cw-radio-button>
  <cw-radio-button value="center">Center</cw-radio-button>
  <cw-radio-button value="right">Right</cw-radio-button>
</cw-segmented-button>
import CwRadioButton from '@cordwainer/cw-elements/dist/react/radio-button';
import CwSegmentedButton from '@cordwainer/cw-elements/dist/react/segmented-button';

const App = () => (
  <>
    <CwSegmentedButton size="small" value="left">
      <CwRadioButton value="left">Left</CwRadioButton>
      <CwRadioButton value="center">Center</CwRadioButton>
      <CwRadioButton value="right">Right</CwRadioButton>
    </CwSegmentedButton>
    <br />
    <CwSegmentedButton size="medium" value="left">
      <CwRadioButton value="left">Left</CwRadioButton>
      <CwRadioButton value="center">Center</CwRadioButton>
      <CwRadioButton value="right">Right</CwRadioButton>
    </CwSegmentedButton>
    <br />
    <CwSegmentedButton size="large" value="left">
      <CwRadioButton value="left">Left</CwRadioButton>
      <CwRadioButton value="center">Center</CwRadioButton>
      <CwRadioButton value="right">Right</CwRadioButton>
    </CwSegmentedButton>
  </>
);

Disabling a Segment

Add the disabled attribute to an individual radio button to prevent it from being selected.

Left Center Right
<cw-segmented-button value="left">
  <cw-radio-button value="left">Left</cw-radio-button>
  <cw-radio-button value="center" disabled>Center</cw-radio-button>
  <cw-radio-button value="right">Right</cw-radio-button>
</cw-segmented-button>
import CwRadioButton from '@cordwainer/cw-elements/dist/react/radio-button';
import CwSegmentedButton from '@cordwainer/cw-elements/dist/react/segmented-button';

const App = () => (
  <CwSegmentedButton value="left">
    <CwRadioButton value="left">Left</CwRadioButton>
    <CwRadioButton value="center" disabled>
      Center
    </CwRadioButton>
    <CwRadioButton value="right">Right</CwRadioButton>
  </CwSegmentedButton>
);

Disabling the Entire Control

Add the disabled attribute to the segmented button itself to disable every segment at once.

Left Center Right
<cw-segmented-button disabled>
  <cw-radio-button value="left">Left</cw-radio-button>
  <cw-radio-button value="center">Center</cw-radio-button>
  <cw-radio-button value="right">Right</cw-radio-button>
</cw-segmented-button>
import CwRadioButton from '@cordwainer/cw-elements/dist/react/radio-button';
import CwSegmentedButton from '@cordwainer/cw-elements/dist/react/segmented-button';

const App = () => (
  <CwSegmentedButton disabled>
    <CwRadioButton value="left">Left</CwRadioButton>
    <CwRadioButton value="center">Center</CwRadioButton>
    <CwRadioButton value="right">Right</CwRadioButton>
  </CwSegmentedButton>
);

Validation

Set the required attribute to make selecting a segment mandatory. If no segment is selected, it will prevent the form from submitting and display an error message.

Left Center Right Submit
<form class="segmented-button-validation">
  <cw-segmented-button label="Alignment" name="alignment" required>
    <cw-radio-button value="left">Left</cw-radio-button>
    <cw-radio-button value="center">Center</cw-radio-button>
    <cw-radio-button value="right">Right</cw-radio-button>
  </cw-segmented-button>
  <cw-button type="submit" variant="primary">Submit</cw-button>
</form>

<style>
  .segmented-button-validation {
    display: flex;
    align-items: center;
    gap: var(--cw-spacing-medium);
  }
</style>

<script>
  const form = document.querySelector('.segmented-button-validation');

  form.addEventListener('submit', event => {
    event.preventDefault();
    alert('All fields are valid!');
  });
</script>
import CwButton from '@cordwainer/cw-elements/dist/react/button';
import CwRadioButton from '@cordwainer/cw-elements/dist/react/radio-button';
import CwSegmentedButton from '@cordwainer/cw-elements/dist/react/segmented-button';

const css = `
  .segmented-button-validation {
    display: flex;
    align-items: center;
    gap: var(--cw-spacing-medium);
  }
`;

const App = () => {
  function handleSubmit(event) {
    event.preventDefault();
    alert('All fields are valid!');
  }

  return (
    <>
      <form className="segmented-button-validation" onSubmit={handleSubmit}>
        <CwSegmentedButton label="Alignment" name="alignment" required>
          <CwRadioButton value="left">Left</CwRadioButton>
          <CwRadioButton value="center">Center</CwRadioButton>
          <CwRadioButton value="right">Right</CwRadioButton>
        </CwSegmentedButton>
        <CwButton type="submit" variant="primary">
          Submit
        </CwButton>
      </form>

      <style>{css}</style>
    </>
  );
};

Importing

If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.

Script Import Bundler React

To import this component from the CDN using a script tag:

<script type="module" src="https://cdn.jsdelivr.net/npm/@cordwainer/cw-elements@1.5.2/cdn/components/segmented-button/segmented-button.js"></script>

To import this component from the CDN using a JavaScript import:

import 'https://cdn.jsdelivr.net/npm/@cordwainer/cw-elements@1.5.2/cdn/components/segmented-button/segmented-button.js';

To import this component using a bundler:

import '@cordwainer/cw-elements/dist/components/segmented-button/segmented-button.js';

To import this component as a React component:

import CwSegmentedButton from '@cordwainer/cw-elements/dist/react/segmented-button';

Slots

Name Description
(default) One or more <cw-radio-button> elements to display as segments.

Learn more about using slots.

Properties

Name Description Reflects Type Default
label A label to use for the segmented button. This won’t be displayed on the screen, but it will be announced by assistive devices when interacting with the control and is strongly recommended. string ''
name The name of the segmented button, submitted as a name/value pair with form data. string 'option'
value The current value of the segmented button, submitted as a name/value pair with form data. string ''
size The segmented button’s size. Applied to every child <cw-radio-button>. 'small' | 'medium' | 'large' 'medium'
disabled Disables the entire segmented button, blocking interaction and excluding it from constraint validation. boolean false
form By default, form controls are associated with the nearest containing <form> element. This attribute allows you to place the form control outside of a form and associate it with the form that has this id. The form must be in the same document or shadow root for this to work. string ''
required Ensures a segment is selected before allowing the containing form to submit. boolean false
validity Gets the validity state object. - -
validationMessage Gets the validation message. - -
updateComplete A read-only promise that resolves when the component has finished updating.

Learn more about attributes and properties.

Events

Name React Event Description Event Detail
cw-change onCwChange Emitted when the selected value changes. -
cw-input onCwInput Emitted when the segmented button receives user input. -
cw-invalid onCwInvalid Emitted when the form control has been checked for validity and its constraints aren’t satisfied. -

Learn more about events.

Methods

Name Description Arguments
checkValidity() Checks for validity but does not show a validation message. Returns true when valid and false when invalid. -
getForm() Gets the associated form, if one exists. -
reportValidity() Checks for validity and shows the browser’s validation message if the control is invalid. -
setCustomValidity() Sets a custom validation message. Pass an empty string to restore validity. message:
focus() Sets focus on the segmented button. options: FocusOptions

Learn more about methods.

Parts

Name Description
base The component’s base wrapper.

Learn more about customizing CSS parts.