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

@efficiency-point/design-system

v0.0.19

Published

Efficiency-point react design system

Readme

Efficiency Point Design System

React/TypeScript дизайн-система с CSS Modules, публичными типами, Storybook и библиотечной сборкой ESM/CJS.

Требования

  • Node.js, совместимый с Vite 8;
  • React и React DOM >=18 <20 в приложении-потребителе;
  • npm как пакетный менеджер.

Подключение

npm install @efficiency-point/design-system
import { DSButton, DSInfoBlock } from '@efficiency-point/design-system';
import '@efficiency-point/design-system/styles.css';

export function Example() {
    return (
        <DSInfoBlock title="Информация">
            <DSButton>Продолжить</DSButton>
        </DSInfoBlock>
    );
}

Компоненты форм контролируемые: value/checked хранится у приложения и обновляется через callback.

Темизация

Компоненты используют CSS custom properties из tokens.css. Их можно переопределить после импорта библиотечного CSS:

:root {
    --color-primary: #2563eb;
    --border-radius: 12px;
    --ds-dropdown-menu-max-height: 280px;
}

Компоненты

DSButton

Кнопка с вариантами primary, secondary, outline, ghost, empty, destructive, destructiveOutline и размерами sm, md, lg.

<DSButton variant="primary" isLoading={saving} onClick={save}>
    Сохранить
</DSButton>

type по умолчанию равен button. При isLoading кнопка блокируется и получает aria-busy.

DSInput

Текстовое или числовое контролируемое поле с label, hint, error, required и очисткой.

<DSInput
    label="Название"
    value={name}
    onChange={(value) => setName(String(value))}
    error={nameError}
    required
/>

DSCheckbox

Поддерживает controlled state, indeterminate, readOnly, disabled, hint/error и нативные form-атрибуты.

<DSCheckbox checked={enabled} onChange={setEnabled} label="Активен" />

DSRadioButton

Двухпозиционный switch. Несмотря на историческое имя, в DOM используется checkbox с role="switch".

<DSRadioButton checked={enabled} onChange={setEnabled} label="Уведомления" />

DSDropDown

Одиночный выбор. Поддерживаются disabled options, hint/error, disabled display и клавиши ArrowUp/ArrowDown, Home, End, Enter, Space, Escape и Tab.

<DSDropDown
    label="Статус"
    options={[{ label: 'Активен', value: 'active' }]}
    value={status}
    onChange={setStatus}
    maxMenuHeight={280}
/>

Высота списка по умолчанию задаётся --ds-dropdown-menu-max-height: 240px; содержимое прокручивается, активная keyboard-опция подводится в видимую область.

DSDropDownMultiple

Множественный controlled dropdown. onChange возвращает массив значений и выбранные объекты. По умолчанию меню остаётся открытым после выбора.

<DSDropDownMultiple
    options={options}
    value={selectedIds}
    onChange={setSelectedIds}
    closeOnSelect={false}
/>

DSDateTimePicker

Контролируемое поле для date, time или datetime. Использует нативные browser controls и принимает Date | null, min и max.

<DSDateTimePicker mode="datetime" value={date} onChange={setDate} />

DSDateRange

Контролируемый диапазон дат или локальных даты/времени. onChange получает только завершённую валидную пару Date; промежуточное состояние доступно через onDraftChange.

<DSDateRange mode="datetime" value={range} onChange={setRange} onDraftChange={setDraftRange} />

DSDataTable и DSSort

Типизированная таблица на стабильной @tanstack/react-table с обязательной сортировкой. По умолчанию мобильный вид отображает строки карточками; tableOnMobile сохраняет таблицу. breakpoint="default" переключает вид ниже 640 px, breakpoint="wide" — ниже 1280 px.

<DSDataTable columns={columns} data={rows} breakpoint="wide" />

DSSort можно использовать отдельно для сортировки по полям объектов или строковым значениям.

DSFilters

Контролируемая композиция фильтров типов input, dropdown, multiple, checkbox, radio и dateRange, построенная из компонентов дизайн-системы.

<DSFilters filters={filters} values={values} onChange={setValues} />

DSVideoPlayerFrame

Адаптивная оболочка нативного видеоплеера с несколькими sources/tracks, poster, media-настройками и loading/error-состояниями.

<DSVideoPlayerFrame title="Обучение" sources={[{ src: '/video.mp4', type: 'video/mp4' }]} />

DSInfoBlock

Постоянно видимая карточка-виджет с заголовком и произвольным содержимым. dismissible только показывает кнопку; скрытием управляет приложение через onDismiss.

{visible && (
    <DSInfoBlock title="Сводка" dismissible onDismiss={() => setVisible(false)}>
        Контент
    </DSInfoBlock>
)}

DSBadge

Неинтерактивная метка. Варианты: neutral, info, success, warning, error; размеры sm, md; доступны dot и icon.

<DSBadge variant="success" dot>Готово</DSBadge>

DSSkeleton

Декоративный placeholder с вариантами text, rectangular, circular, несколькими строками и отключаемой анимацией. Skeleton скрыт от accessibility tree; aria-busy должен задавать родитель.

<section aria-busy="true"><DSSkeleton lines={3} /></section>

DSTooltip

Короткая неинтерактивная подсказка. Открывается по hover/focus/touch, закрывается по blur, pointer leave и Escape. Для кнопок и ссылок внутри содержимого используйте popover, а не tooltip.

<DSTooltip content="Редактировать" placement="top">
    <button type="button">...</button>
</DSTooltip>

DSLoader и DSPageLoader

DSLoader — компактный индикатор с role="status" или декоративным режимом. DSPageLoader — центрированный loading-state области страницы.

DSIcon

Типизированный registry иконок. Публичен union DSIconName. Без title иконка декоративная; с title получает роль изображения и доступное имя.

<DSIcon name="approve" title="Подтверждено" />

Field primitives

DSFieldLabel и DSFieldMessage унифицируют label, required marker, optional text, hint/error/success сообщения. Публичны все props и DSFieldMessageVariant.

Toast

Toast использует внутренний Zustand store и публичный useToast. Provider обычно подключается один раз рядом с корнем приложения.

function Root() {
    return (
        <>
            <App />
            <DSToastProvider position="top-right" />
        </>
    );
}

function SaveButton() {
    const { successToast } = useToast();
    return (
        <DSButton onClick={() => successToast({ message: 'Сохранено' })}>
            Сохранить
        </DSButton>
    );
}

Расширенный API экспортирует useToastStore, ToastStoreState, ToastItem, ShowToastPayload, ToastAction и ToastVariant.

Modal и реестр приложения

Библиотека не импортирует файлы consumer-проекта. Каждый проект хранит реестр по принятому пути, например src/shared/ui/modal/modal.registry.tsx, и явно передаёт его provider.

// src/shared/ui/modal/modal.registry.tsx
import {
    builtInModalRegistry,
    defineModalRegistry,
    type ModalControls,
} from '@efficiency-point/design-system';
import { EmployeeModal } from './EmployeeModal';

export type EmployeeModalPayload = {
    employeeId: string;
};

export const modalRegistry = defineModalRegistry({
    ...builtInModalRegistry,
    EmployeeModal: ({ employeeId, modalId, close }: EmployeeModalPayload & ModalControls) => (
        <div data-modal-id={modalId}>
            Сотрудник: {employeeId}
            <button onClick={close}>Закрыть</button>
        </div>
    ),
});

export type AppModalRegistry = typeof modalRegistry;
// app providers
import { ModalSystemProvider } from '@efficiency-point/design-system';
import { modalRegistry } from '@/shared/ui/modal/modal.registry';

<ModalSystemProvider registry={modalRegistry}>
    <App />
</ModalSystemProvider>
const { openModal } = useModals<typeof modalRegistry>();
openModal('EmployeeModal', { employeeId: '42' });

Modal host поддерживает stack, закрытие верхней модалки по Escape, backdrop-close, focus trap и восстановление focus. Поведение Escape/backdrop настраивается в openModal.

Встроенные ConfirmModal и ErrorModal доступны через builtInModalRegistry, useConfirmModal и useErrorModal.

Публичные типы

Все component props, callback signatures, variant unions, store states, hook results, modal registry contracts и payload-типы экспортируются из корневого entry point.

Разработка и проверки

npm run lint
npm run typecheck
npm run test
npm run test:coverage
npm run build
npm run test:package
npm run build-storybook
npm run pack:check

Подготовка пакета

  1. Установить зависимости: npm ci.
  2. Запустить npm run lint.
  3. Запустить npm run typecheck.
  4. Запустить npm run test и сохранить результаты в отчёт.
  5. Запустить npm run test:package.
  6. Собрать Storybook: npm run build-storybook.
  7. Проверить содержимое архива: npm run pack:check.
  8. Указать финальные name, version, license, repository и при необходимости publishConfig в package.json.
  9. Создать архив: npm pack.
  10. Установить .tgz в чистое React-приложение и проверить ESM/CJS, типы и CSS.
  11. После проверки выполнить npm publish в выбранный registry. Публикация и изменение версии выполняются отдельно и в текущую задачу не входят.

Подключение к другому проекту

  1. Установить опубликованный пакет или локальный tarball.
  2. Один раз импортировать @efficiency-point/design-system/styles.css в entry приложения.
  3. Убедиться, что React/React DOM удовлетворяют peer range.
  4. Подключить DSToastProvider, если используются toast.
  5. Создать shared/ui/modal/modal.registry.tsx и подключить ModalSystemProvider, если используются модалки.
  6. Заменять локальные UI-компоненты постепенно, сохраняя controlled state и импортируя публичные props/payload-типы из пакета.