组件 · 导航
SegmentedControl
2 to 4 segments in a gray track that switch how the same content is shown, in place; the selected segment is a yellow sticker.
也叫 Segmented button
import { SegmentedControl } from "@botiverse/raft-ui";A segmented control switches between 2 to 4 views of the same content, in place: a board or a list of the same tasks, a light or a dark appearance. The segments sit in a gray track, and the selected one is a yellow sticker.
When to use
| Situation | Use |
|---|---|
| Another view of the same content: Board / List, Light / Dark / System | SegmentedControl |
| Sections of one page, each with its own content | Tabs |
| An answer submitted with a form | RadioGroup |
| More options than fit as segments | Select |
The full table is in Choosing a component. Where Board / List goes on a task list is in Tasks.
Anatomy
SegmentedControl: the track, infill-muted.SegmentedControlItem: one 32px segment, with an optional icon before its label.SegmentedControlLabel: the segment's text. It truncates.SegmentedControlCount: a count after the label, in Space Mono.
States
- Selected: a yellow sticker with a bold label. It doesn't change on hover, like a selected tab; a press lays
sticker-medium(Hover and press). - The other segments are
foreground-muted, with the medium tier,fill-medium, on hover and press. - Disabled: set on the whole control, as in States.
Behavior
- The segments sit 3px inside the track and 3px apart, so the gap between two of them is the gap to the track (Spacing).
- The track hugs its segments. Don't stretch it to fill its container: a stretched track leaves an empty run of gray beside the segments.
- The control never shrinks below its segments. When the row is too narrow, its neighbors give way first, then the segments show only their icons (Responsive layout).
- To let the segments show only their icons, mark the row with
@containerand seticonsOnlyBelowon the control to the row width below which the labels no longer fit:xs(20rem),sm(24rem),md(28rem),lg(32rem),xl(36rem) or2xl(42rem). Below it, every segment becomes a 32px square that shows only its icon: its label and its count stay its accessible name, and its label shows in a tooltip on hover and on keyboard focus. The control keeps its 32px height and its text size. SeticonsOnlyBelowonly when every segment has an icon: a segment without one would be left empty. - Pick the width from the row, not the window: the same row sits in columns of different widths, and a container query follows the column.
- Stretch it only when it is the only choice in a form. Then give it the full width (
w-full) on its own line, not in a row beside other controls, and let the segments share it equally: in a row, a full-width track that can't shrink pushes past its neighbors. - On a phone, use at most 4 segments and show only their icons when they don't fit, with
iconsOnlyBelow(Responsive layout).
Content
- Label each segment with 1 or 2 words in Title Case: Board, List; Relevant, Recent (Typography).
- Put a count in
SegmentedControlCount, never in the label's text.
Accessibility
SegmentedControlwraps the Base UI RadioGroup, and eachSegmentedControlItemis a Base UI Radio rendered as a button: the control is one tab stop, and the arrow keys move the selection.- Name the control with
aria-labelafter what it switches: "Task view", "Time format". - Give every icon-only segment an
aria-label. A segment that shows only its icon because oficonsOnlyBelowneeds none: its label is still in it, hidden from sight but not from assistive technology.
API
SegmentedControl
| Prop | 类型 | 默认值 |
|---|---|---|
| When the nearest `@container` ancestor (the row the control sits in) is narrower than this width, every segment shows only its icon (give each one). Its label stays the accessible name and shows in a tooltip. | SegmentedControlIconsOnlyBelow | |
| The uncontrolled value of the radio button that should be initially selected. | T | |
| Whether the component should ignore user interaction. | boolean | false |
| Identifies the form that owns the radio inputs. Useful when the radio group is rendered outside the form. | string | |
| A ref to access the hidden input element. | ((instance: HTMLInputElement | null) => void | (() => void | { [UNDEFINED_VOID_ONLY]: never; }) | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | RefObject<HTMLInputElement | null> | |
| Identifies the field when a form is submitted. | string | |
| Callback fired when the value changes. | (value: T, eventDetails: BaseRadioGroup.ChangeEventDetails) => void | |
| Whether the user should be unable to select a different radio button in the group. | boolean | false |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) | |
| Whether the user must choose a value before submitting a form. | boolean | false |
| The controlled value of the radio item that should be currently selected. | T |
Also takes the attributes of its element.
SegmentedControlCount
接受其元素的全部属性。
SegmentedControlItem
| Prop | 类型 | 默认值 |
|---|---|---|
| Whether the component should ignore user interaction. | boolean | |
| A ref to access the hidden input element. | ((instance: HTMLInputElement | null) => void | (() => void | { [UNDEFINED_VOID_ONLY]: never; }) | DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | RefObject<HTMLInputElement | null> | |
| Whether the component renders a native `<button>` element when replacing it via the `render` prop. Set to `true` if the rendered element is a native button. | boolean | false |
| Whether the user should be unable to select the radio button. | boolean | |
| Allows you to replace the component's HTML element with a different tag, or compose it with another component. | ReactElement | ((props, state) => ReactElement) | |
| Whether the user must choose a value before submitting a form. | boolean | |
| The unique identifying value of the radio in a group. | T |
Also takes the attributes of its element.
SegmentedControlLabel
接受其元素的全部属性。
相关组件
改动
- 0.9.0 · Added
SegmentedControltakesiconsOnlyBelow("xs"to"2xl", Tailwind's container sizes; typeSegmentedControlIconsOnlyBelow). Mark the row@container; below that width each segment shows only its icon as a 32px square, its label and count stay the accessible name, and a tooltip shows the label. Use it only when every segment has an icon. - 0.8.0 · Breaking Changes
SegmentedControlno longer shrinks withmax-w-full; it keeps its width (shrink-0). In a narrow row, give it room or let the row degrade asresponsive.mdsays, or it overflows. - 0.8.0 · Fixed
SegmentedControlkeeps its width and no longer gets squeezed by a neighbor in the same row.