npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@cloud-ru/ds-segment-control

v1.0.6

Published

Сегментированный переключатель — компактная радио-группа с единственным выбором, токенами размеров s/m/l, иконками, счётчиками и режимом полной ширины.

Readme

SegmentControl

@cloud-ru/ds-segment-control — Сегментированный переключатель — компактная радио-группа с единственным выбором, токенами размеров s/m/l, иконками, счётчиками и режимом полной ширины.

Радио-группа с единственным выбором, оформленная как сегментированный контрол. Подходит для переключения режимов отображения, фильтров с малым числом значений и компактных табов на плотных поверхностях. Поддерживает controlled и uncontrolled режим, клавиатурную навигацию (Arrow/Home/End с пропуском disabled), иконки, счётчики и режим полной ширины.

Когда использовать

  • Когда вариантов от 2 до 5 и все они одновременно видимы на экране.
  • Для переключения режимов отображения (list/grid/kanban, day/week/month).
  • Для компактных фильтров с взаимоисключающим выбором.

Когда не нужен SegmentControl:

  • Вариантов больше 5:
    • используйте Tabs или Select.
  • Допускается множественный выбор:
    • используйте чекбоксы или ToggleGroup.
  • Выбор приводит к загрузке тяжёлого контента и нужны отдельные урлы:
    • используйте Tabs.

Анатомия

Size (default m)

Размерный ряд: s / m / l — стандартные плотности.

Width (default auto)

  • auto — ширина по контенту.
  • full — растягивает контейнер на всю ширину родителя, сегменты делят ширину поровну. Уместен в формах и фильтрах с фиксированной шириной поля.

Outline (default false)

Булевый флаг — добавляет обводку контейнеру. Используется на «лёгких» поверхностях, где контрол должен явно отделяться от фона.

Segment slots

Каждый элемент items[i] собирается из:

  • label — текст сегмента.
  • icon — иконка с iconPosition: 'before' | 'after'.
  • counter — счётчик после label.

Дополнительно:

  • Сегмент может быть icon-only (без label).
  • Отдельный сегмент можно сделать disabled — клавиатурная навигация его пропускает.

Установка

pnpm add @cloud-ru/ds-segment-control
import { SegmentControl } from '@cloud-ru/ds-segment-control'

Примеры использования

1. Базовый сценарий

Uncontrolled режим через defaultValue — компонент сам хранит выбор

import { SegmentControl } from '@cloud-ru/ds-segment-control';

export function Basic() {
  return (
    <SegmentControl
      defaultValue='overview'
      items={[
        { value: 'overview', label: 'Overview' },
        { value: 'analytics', label: 'Analytics' },
        { value: 'reports', label: 'Reports' },
      ]}
    />
  );
}

2. Все размеры

s / m / l

import { SegmentControl } from '@cloud-ru/ds-segment-control';

const items = [
  { value: 'one', label: 'One' },
  { value: 'two', label: 'Two' },
  { value: 'three', label: 'Three' },
];

export function Sizes() {
  return (
    <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
      <SegmentControl size='s' defaultValue='one' items={items} />
      <SegmentControl size='m' defaultValue='one' items={items} />
      <SegmentControl size='l' defaultValue='one' items={items} />
    </div>
  );
}

3. С иконками и icon-only

label + icon, или icon без label для плотных тулбаров

import { HomeSVG, PlusSVG, SettingsSVG } from '@cloud-ru/ds-icons/interface/system';
import { SegmentControl } from '@cloud-ru/ds-segment-control';

export function WithIcons() {
  return (
    <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
      <SegmentControl
        defaultValue='home'
        items={[
          { value: 'home', label: 'Home', icon: <HomeSVG /> },
          { value: 'settings', label: 'Settings', icon: <SettingsSVG /> },
          { value: 'add', label: 'Add', icon: <PlusSVG /> },
        ]}
      />
      <SegmentControl
        defaultValue='home'
        items={[
          { value: 'home', icon: <HomeSVG /> },
          { value: 'settings', icon: <SettingsSVG /> },
          { value: 'add', icon: <PlusSVG /> },
        ]}
      />
    </div>
  );
}

4. Со счётчиком

counter рендерится после label и переиспользует @cloud-ru/ds-counter

import { SegmentControl } from '@cloud-ru/ds-segment-control';

export function WithCounter() {
  return (
    <SegmentControl
      defaultValue='inbox'
      items={[
        { value: 'inbox', label: 'Inbox', counter: 12 },
        { value: 'drafts', label: 'Drafts', counter: 3 },
        { value: 'archive', label: 'Archive' },
      ]}
    />
  );
}

5. Полная ширина и outline

width='full' растягивает на родителя; outline даёт обводку контейнера

import { SegmentControl } from '@cloud-ru/ds-segment-control';

export function FullWidth() {
  return (
    <div style={{ width: 480, maxWidth: '100%' }}>
      <SegmentControl
        width='full'
        outline
        defaultValue='day'
        items={[
          { value: 'day', label: 'Day' },
          { value: 'week', label: 'Week' },
          { value: 'month', label: 'Month' },
          { value: 'year', label: 'Year' },
        ]}
      />
    </div>
  );
}

6. Disabled сегмент

Клавиатурная навигация Arrow/Home/End пропускает заблокированные элементы

import { SegmentControl } from '@cloud-ru/ds-segment-control';

export function DisabledSegment() {
  return (
    <SegmentControl
      defaultValue='one'
      items={[
        { value: 'one', label: 'One' },
        { value: 'two', label: 'Two', disabled: true },
        { value: 'three', label: 'Three' },
      ]}
    />
  );
}

7. Controlled с useState

value + onChange когда нужен внешний источник правды

import { SegmentControl } from '@cloud-ru/ds-segment-control';
import { useState } from 'react';

export function Controlled() {
  const [view, setView] = useState<'list' | 'grid' | 'kanban'>('list');

  return (
    <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap', alignItems: 'center' }}>
      <SegmentControl
        value={view}
        onChange={setView}
        items={[
          { value: 'list', label: 'List' },
          { value: 'grid', label: 'Grid' },
          { value: 'kanban', label: 'Kanban' },
        ]}
      />
      <span>Selected: {view}</span>
    </div>
  );
}

Props

SegmentControlProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | className | string | — | CSS-класс контейнера. | | data-test-id | string | — | | | defaultValue | IdType | — | ID выбранного по умолчанию сегмента (uncontrolled). | | items | Segment | — | Набор сегментов. | | name | string | — | Имя поля (hidden input для формы). | | onChange | ((value: Value) => void) | — | Колбек смены выбранного сегмента. | | outline | boolean | — | Обводка. | | size | "l" | "m" | "s" | m | Размер компонента. | | value | IdType | — | Value выбранного сегмента. | | width | "auto" | "full" | auto | Управление шириной компонента. |

Related types

  • IconPosition = "after" | "before"

Segment

| Prop | Type | Default | Description | |------|------|---------|-------------| | counter | string \| number \| undefined | — | Счётчик в сегменте (отображается после лейбла). | | disabled | boolean \| undefined | — | Состояние активности сегмента. | | icon | string \| number \| boolean \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| null \| undefined | — | Иконка сегмента. | | iconPosition | "after" | "before" | — | Позиция иконки относительно лейбла. | | label | string \| undefined | — | Текстовый заголовок сегмента. | | renderWrapSegment | ((segment: ReactNode) => ReactNode) \| undefined | — | Render-обёртка над сегментом. | | value | Value | — | Идентификатор сегмента. |

  • Size = "l" | "m" | "s"

  • Width = "auto" | "full"