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-alert

v1.1.0

Published

Семантическое уведомление — компонент Alert для inline-нотификаций в контенте и AlertTop для системных баннеров по верхней кромке.

Readme

Alert

@cloud-ru/ds-alert — Семантическое уведомление — компонент Alert для inline-нотификаций в контенте и AlertTop для системных баннеров по верхней кромке.

Пакет @cloud-ru/ds-alert предоставляет два варианта уведомлений:

  • Alert — inline-алерт внутри страницы: в форме, в карточке, в списке. Поддерживает actions, close-кнопку и режим сворачивания.
  • AlertTop — системный баннер, который крепится к верхней кромке страницы. Всегда на сплошной цветной подложке.

Установка

pnpm add @cloud-ru/ds-alert
import { Alert, AlertTop } from '@cloud-ru/ds-alert'

Alert

Inline-уведомление внутри контента — шесть appearance, два размера, режим сворачивания, горизонтальное и вертикальное выравнивание, опциональные actions и close.

Inline-уведомление, которое живёт в контенте — в форме, в карточке, в списке. Шесть appearance задают семантику, две оси (size, align) — форму, а пропсы actions, onClose, collapsible — поведение.

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

  • Для подтверждения результата действия (success / error).
  • Для предупреждения перед необратимой операцией (warning).
  • Для информационного контекста внутри формы (info).

Когда не нужен: для коротких эфемерных сообщений («Скопировано», «Сохранено») используйте toast — Alert остаётся видимым, пока его не закрыть.

Анатомия

Appearance

Семантическая роль сообщения: neutral/primary — нейтральная/информативная подача, info — информ-акцент, success — успешное завершение, warning — предупреждение о потенциальной проблеме, error — ошибка или блокирующее состояние.

Align

Выравнивание заголовка и контента: horizontal — заголовок и текст в одну строку, vertical — заголовок над текстом (для длинного контента и экшенов).

Size

Компактность inline-алерта: s — для плотных поверхностей и табличных строк, m — дефолт.

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

1. Информационный алерт

import { Alert } from '@cloud-ru/ds-alert';

export function Info() {
  return (
    <Alert appearance='info' title='Настройки сохранены' content='Изменения применены ко всем активным проектам.' />
  );
}

2. Ошибка с close-кнопкой

import { Alert } from '@cloud-ru/ds-alert';

export function Error() {
  return (
    <Alert
      appearance='error'
      title='Не удалось сохранить'
      content='Проверьте подключение к сети и повторите попытку.'
      onClose={() => undefined}
    />
  );
}

3. Алерт с действиями

import { Alert } from '@cloud-ru/ds-alert';

export function WithActions() {
  return (
    <Alert
      appearance='warning'
      title='Требуется подтверждение'
      content='Операция необратима. Продолжить?'
      actions={{
        primary: { label: 'Продолжить', onClick: () => undefined },
        secondary: { label: 'Отмена', onClick: () => undefined },
      }}
    />
  );
}

4. Сворачиваемый алерт

import { Alert } from '@cloud-ru/ds-alert';

export function Collapsible() {
  return (
    <Alert
      appearance='info'
      collapsible
      title='Совет по настройке'
      content='Полное описание того, как правильно настроить функцию. Текст длинный и сворачивается до раскрытия.'
    />
  );
}

Props

AlertProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | actions | AlertButtonProps | — | Кнопки в футере | | align | "horizontal" | "vertical" | vertical | Выравнивание контента | | appearance | "error" | "info" | "neutral" | "primary" | "success" | "warning" | — | Внешний вид | | className | string | — | CSS-класс | | collapsible | boolean | — | Режим сворачивания: длинный текст, ссылка и кнопки скрыты до раскрытия (inline; как MobileAlertTop). При true не используйте TruncateString на том же узле, что и измерение — см. документацию. | | content | ReactNode | — | Описание | | data-test-id | string | — | | | icon | boolean | — | Отображать иконку | | layoutPresets | AlertLayoutDefaults | LayoutPresets | — | Override mobile-дефолтов адаптива для этого инстанса (deep-merge поверх ALERT_LAYOUT_PRESETS). Escape-hatch: обычно не нужен — DS-пресет применяется автоматически по AdaptiveProvider. | | onClose | (() => void) | — | Колбек закрытия | | outline | boolean | — | Внешний бордер | | size | "m" | "s" | — | Размер | | title | string | — | Заголовок | | truncate | { title?: number; } | title: 1 | Максимальное кол-во строк (только при collapsible={false}). |

Related types

AlertButtonProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | as | T \| undefined | — | Элемент или компонент для рендера: 'button' | 'a' | ComponentType (например Link из react-router-dom) | | className | string \| undefined | — | Дополнительный класс | | disabled | boolean \| undefined | — | Отключена | | icon | string \| number \| boolean \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| null \| undefined | — | Иконка | | iconPosition | "after" | "before" | — | Позиция иконки относительно текста | | innerRef | PolymorphicRef | — | Ref на реальный DOM-элемент/инстанс, который рендерится через as. Используем явный проп, чтобы не зависеть от forwardRef и не тащить type-assertions на экспорт. | | invertFocusOutlineColor | boolean \| undefined | — | Инвертировать цвет фокусного контура | | label | string \| undefined | — | Текст кнопки | | loading | boolean \| undefined | — | Состояние загрузки | | size | "m" | "s" | — | Размер | | variant | "onAccent" | "onColor" | — | Вариант оформления |

AlertLayoutDefaults

| Prop | Type | Default | Description | |------|------|---------|-------------| | truncate | { title?: number; } \| undefined | — | Максимальное кол-во строк (только при collapsible={false}). |

  • Align = "horizontal" | "vertical"

  • Appearance = "error" | "info" | "neutral" | "primary" | "success" | "warning"

  • ButtonSize = "m" | "s"

  • ButtonVariant = "onAccent" | "onColor"

  • IconPosition = "after" | "before"

  • PolymorphicRef = ComponentPropsWithRef<T>["ref"]

  • Size = "m" | "s"

Адаптивность

Alert — адаптивный компонент класса preset-defaults: DOM один, по раскладке меняются только дефолты пропсов. Раскладку компонент читает из контекста @cloud-ru/ds-adaptive — отдельного пропа layoutType нет.

Desktop-first. Верстайте под desktop и поставьте один <AdaptiveProvider> в корне приложения — mobile-дефолты применяются автоматически. Override нужен только как escape-hatch.

На mobile заголовок усекается до двух строк вместо одной — на узких экранах это сохраняет читаемость без обрезки полезного текста.

| Проп | desktop | mobile | |------|---------|--------| | truncate.title | 1 | 2 |

Источник mobile-дефолтов — экспортируемая константа ALERT_LAYOUT_PRESETS.

Как переопределить

Desktop-first: перенос пропа из desktop-макета не ломает mobile. Приоритет (от высшего к низшему): layoutPresets[layout] (инстанс) → DS-пресет ALERT_LAYOUT_PRESETS → явный проп (= desktop-значение) → базовый дефолт.

import { Alert } from '@cloud-ru/ds-alert'

// 1. Явный проп — задаёт DESKTOP-значение; mobile остаётся 2 строки (mobile не ломается)
<Alert truncate={{ title: 3 }} title='…' content='…' />

// 2. layoutPresets.mobile — единственный способ изменить mobile (явно)
<Alert layoutPresets={{ mobile: { truncate: { title: 3 } } }} title='…' content='…' />

// 2b. layoutPresets.desktop — изменить только desktop, mobile-адаптив сохранён
<Alert layoutPresets={{ desktop: { truncate: { title: 3 } } }} title='…' content='…' />

DS-пресет (ALERT_LAYOUT_PRESETS) — точка форка mobile-дефолтов на уровне всей дизайн-системы.

Как форсировать раскладку

Раскладка переключается только контекстом, не пропом:

import { AdaptiveProvider, withLayoutType } from '@cloud-ru/ds-adaptive'
import { Alert } from '@cloud-ru/ds-alert'

// поддерево — вложенный провайдер
<AdaptiveProvider layoutType='mobile'>
  <Alert title='…' content='…' />
</AdaptiveProvider>

// компонент/секция — HOC (module-scope, не в рендере)
const MobileAlert = withLayoutType(Alert, 'mobile')

Подробнее о модели раскладки — в @cloud-ru/ds-adaptive.

Mobile — усечение заголовка

Раскладка форсирована в mobile: на узком экране длинный заголовок усекается в две строки вместо одной.

import { AdaptiveProvider, LAYOUT_TYPE } from '@cloud-ru/ds-adaptive';
import { Alert } from '@cloud-ru/ds-alert';

const LONG_TITLE = 'Плановые технические работы в дата-центре: часть сервисов будет недоступна с 02:00 до 04:00 МСК';

export function AdaptiveTruncate() {
  return (
    <AdaptiveProvider layoutType={LAYOUT_TYPE.Mobile}>
      <div style={{ maxWidth: 360 }}>
        <Alert appearance='info' title={LONG_TITLE} content='На узком экране заголовок усекается в две строки.' />
      </div>
    </AdaptiveProvider>
  );
}

Playground ниже показывает только переключение раскладки — сам текст короткий и не переносится ни на одной раскладке (кириллица в URL-args Storybook не резолвится, см. пример выше для наглядного усечения).

AlertTop

Системный баннер по верхней кромке приложения — всегда на сплошной цветной подложке, используется для глобальных уведомлений.

Глобальный баннер, который крепится к верхней кромке приложения. В отличие от Alert, всегда рендерится на сплошной цветной подложке (определяется appearance) и не поддерживает outline — визуально это «полоса сообщения», а не карточка.

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

  • Для плановых технических работ и maintenance-окон.
  • Для глобальных ограничений (например, «В вашем регионе временно недоступны платежи»).
  • Для системных анонсов, которые касаются всех пользователей приложения.

Когда не нужен: для сообщений, которые касаются конкретной страницы или формы — используйте Alert.

Анатомия

Appearance

Семантическая роль топ-баннера: neutral/primary — нейтрально-информативная подача, info — информ-акцент, success — успех (редко в топ-баннере), warning — предупреждение (maintenance), error — критическое ограничение/инцидент.

Align

Выравнивание заголовка и описания: horizontal — в одну строку (короткий анонс), vertical — заголовок над текстом (длинное описание + действие).

Size

Плотность баннера: s — компактный, m — дефолт.

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

Системное уведомление

import { AlertTop } from '@cloud-ru/ds-alert';

export function SystemNotice() {
  return (
    <AlertTop
      appearance='info'
      title='Плановые работы'
      content='Сегодня с 22:00 до 23:00 возможны кратковременные перебои.'
    />
  );
}

Props

AlertTopProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | actions | AlertButtonProps | — | Кнопки в футере | | align | "horizontal" | "vertical" | vertical | Выравнивание контента | | appearance | "error" | "info" | "neutral" | "primary" | "success" | "warning" | — | Внешний вид | | className | string | — | CSS-класс | | collapsible | boolean | — | Режим сворачивания: длинный текст, ссылка и кнопки скрыты до раскрытия (inline; как MobileAlertTop). При true не используйте TruncateString на том же узле, что и измерение — см. документацию. | | content | ReactNode | — | Описание | | data-test-id | string | — | | | icon | boolean | — | Отображать иконку | | layoutPresets | AlertTopLayoutDefaults | LayoutPresets | — | Override mobile-дефолтов адаптива для этого инстанса (deep-merge поверх ALERT_TOP_LAYOUT_PRESETS). Escape-hatch: обычно не нужен — DS-пресет применяется автоматически по AdaptiveProvider. | | onClose | (() => void) | — | Колбек закрытия | | size | "m" | "s" | — | Размер | | title | string | — | Заголовок | | truncate | { title?: number; } | title: 1 | Максимальное кол-во строк (только при collapsible={false}). |

Related types

AlertButtonProps

| Prop | Type | Default | Description | |------|------|---------|-------------| | as | T \| undefined | — | Элемент или компонент для рендера: 'button' | 'a' | ComponentType (например Link из react-router-dom) | | className | string \| undefined | — | Дополнительный класс | | disabled | boolean \| undefined | — | Отключена | | icon | string \| number \| boolean \| ReactElement<any, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| null \| undefined | — | Иконка | | iconPosition | "after" | "before" | — | Позиция иконки относительно текста | | innerRef | PolymorphicRef | — | Ref на реальный DOM-элемент/инстанс, который рендерится через as. Используем явный проп, чтобы не зависеть от forwardRef и не тащить type-assertions на экспорт. | | invertFocusOutlineColor | boolean \| undefined | — | Инвертировать цвет фокусного контура | | label | string \| undefined | — | Текст кнопки | | loading | boolean \| undefined | — | Состояние загрузки | | size | "m" | "s" | — | Размер | | variant | "onAccent" | "onColor" | — | Вариант оформления |

AlertTopLayoutDefaults

| Prop | Type | Default | Description | |------|------|---------|-------------| | collapsible | boolean \| undefined | — | Режим сворачивания: длинный текст, ссылка и кнопки скрыты до раскрытия (inline; как MobileAlertTop). При true не используйте TruncateString на том же узле, что и измерение — см. документацию. |

  • Align = "horizontal" | "vertical"

  • Appearance = "error" | "info" | "neutral" | "primary" | "success" | "warning"

  • ButtonSize = "m" | "s"

  • ButtonVariant = "onAccent" | "onColor"

  • IconPosition = "after" | "before"

  • PolymorphicRef = ComponentPropsWithRef<T>["ref"]

  • Size = "m" | "s"

Адаптивность

AlertTop — адаптивный компонент класса preset-defaults: DOM один, по раскладке меняются только дефолты пропсов. Раскладку компонент читает из контекста @cloud-ru/ds-adaptive — отдельного пропа layoutType нет.

Desktop-first. Верстайте под desktop и поставьте один <AdaptiveProvider> в корне приложения — mobile-дефолты применяются автоматически. Override нужен только как escape-hatch.

На mobile баннер становится раскрываемым (collapsible): длинный текст и действия скрыты до клика по баннеру, на месте close-кнопки появляется шеврон раскрытия. На desktop баннер плоский.

| Проп | desktop | mobile | |------|---------|--------| | collapsible | false | true |

Источник mobile-дефолтов — экспортируемая константа ALERT_TOP_LAYOUT_PRESETS.

Как переопределить

Desktop-first: перенос пропа из desktop-макета не ломает mobile. Приоритет (от высшего к низшему): layoutPresets[layout] (инстанс) → DS-пресет ALERT_TOP_LAYOUT_PRESETS → явный проп (= desktop-значение) → базовый дефолт.

import { AlertTop } from '@cloud-ru/ds-alert'

// 1. Явный проп — задаёт DESKTOP-значение; mobile остаётся collapsible (mobile не ломается)
<AlertTop collapsible={false} title='…' content='…' />

// 2. layoutPresets.mobile — единственный способ изменить mobile (явно)
<AlertTop layoutPresets={{ mobile: { collapsible: false } }} title='…' content='…' />

// 2b. layoutPresets.desktop — изменить только desktop, mobile-адаптив сохранён
<AlertTop layoutPresets={{ desktop: { collapsible: true } }} title='…' content='…' />

DS-пресет (ALERT_TOP_LAYOUT_PRESETS) — точка форка mobile-дефолтов на уровне всей дизайн-системы.

Как форсировать раскладку

Раскладка переключается только контекстом, не пропом:

import { AdaptiveProvider, withLayoutType } from '@cloud-ru/ds-adaptive'
import { AlertTop } from '@cloud-ru/ds-alert'

// поддерево — вложенный провайдер
<AdaptiveProvider layoutType='mobile'>
  <AlertTop title='…' content='…' />
</AdaptiveProvider>

// компонент/секция — HOC (module-scope, не в рендере)
const MobileAlertTop = withLayoutType(AlertTop, 'mobile')

Подробнее о модели раскладки — в @cloud-ru/ds-adaptive.