@studio-west/component-sw

Vue components of Component-SW collection.
31,559
Install
npm install @studio-west/component-sw
Latest Version:1.0.3
Vue:3
License:ISC
Last Updated:Oct 5, 2026
Links: npm
Maintainer: studio-west

Component SW - UI компоненты с поддержкой светлой и темной системной темы

Библиотека компонентов Component SW предоставляет набор готовых UI-компонентов на vue 3 для быстрой разработки интерфейсов. Каждый компонент имеет набор свойств, которые можно настраивать для достижения желаемого поведения и внешнего вида. Имеет поддержку светлой и темной системной темы. А также имеет поддержку мобильных систем разработки.


Component SW - UI Components with Light and Dark Theme Support

The Component SW library provides a set of ready-to-use UI components on Vue 3 for rapid interface development. Each component has a set of properties that can be customized to achieve the desired behavior and appearance. It supports both light and dark system themes. And also has support for mobile development systems.


SSR / Server-Side Rendering

Библиотеку можно безопасно импортировать на сервере: сборка dist/index.js (и dist/index.cjs) не обращается к document/window/navigator на верхнем уровне. Инициализация Alert выполняется лениво и защищена проверкой окружения.

The library is safe to import on the server: the dist/index.js (and dist/index.cjs) bundle no touches document/window/navigator at the top level. Alert initialization is lazy and environment-guarded.


Содержание / Table of Contents

Интерактивный плейграунд последней версии с живыми примерами, демонстрацией компонентов в браузере: studiowest.ru/component-sw.

Interactive playground of the latest version with live examples, demonstration of components in the browser: studiowest.ru/component-sw.


Установка / Install

npm install @studio-west/component-sw 

Registry: npmjs.

Глобальное подключение / global add to main.js

import { Library } from '@studio-west/component-sw';
import '@studio-west/component-sw/dist/component-sw.css';

app.use(Library)

Локальное подключение / Local add:

import { components } from '@studio-west/component-sw';
import '@studio-west/component-sw/dist/component-sw.css';
const { 
  SwSlider,
  SwInput
} = components;

Установка в ручную светлой и темной темы - добавление к тегу html классов dark или light / Installation in a manual light and dark theme - adding to the tag html classes dark or light

Пример использования / Example Usage

const mode = ref((getTheme() === 'dark' || getTheme() !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches)? 'light-theme': 'dark-theme')
const darkMode = () => {
    if(mode.value === 'dark-theme') { // name icon
        document.querySelector('html').classList.remove('light')
        document.querySelector('html').classList.add('dark')
        setTheme('dark') // set cookies
    }
    else {
        document.querySelector('html').classList.remove('dark')
        document.querySelector('html').classList.add('light')
        setTheme('light') // set cookies
    }
    mode.value = (document.querySelector('html').classList.contains('dark')) ? 'light-theme' : 'dark-theme'
}

SwAffix

Фиксирует слот при прокрутке до нижней границы boundary или, если селектор не задан, до конца страницы. Алгоритм бокового меню.

Свойства / Properties

Имя Тип По умолчанию Описание
class String `` CSS-класс обёртки.
offset Number 0 Отступ сверху viewport (px), P в listing.js.
offsetBottom Number 0 Зазор до границы boundary (px); линия фиксации = edge − offsetBottom.
boundary String `` CSS-селектор границы; без него — конец страницы.
boundaryEdge String bottom top | bottom — к какой границе boundary привязка (включительно).

Пример

Два варианта boundary-edge:

<style>
.dev-affix-demos { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; align-items: start; }
.dev-affix-demo > h3 { margin: 0 0 .75rem; font-size: .95rem; font-weight: 600; }
.dev-affix-layout { align-items: stretch; }
.dev-affix-layout > p { margin: 0; }
.dev-affix-aside { min-width: 0; align-self: stretch; }
.dev-affix-panel { background: var(--sw-bg-color-page); padding: .75rem 1rem; opacity: .8; }
.dev-affix-panel > p { margin: 0; }
.dev-affix-demo-menu .dev-affix-layout { display: grid; grid-template-columns: minmax(120px, 160px) 1fr; gap: 1rem; align-items: stretch; }
.dev-affix-demo-menu .dev-affix-aside { grid-column: 1; grid-row: 1; }
.dev-affix-demo-menu .dev-affix-boundary-b { grid-column: 2; grid-row: 1; display: grid; gap: .75rem; }
.dev-affix-demo-menu .dev-affix-boundary-b > p { margin: 0; line-height: 1.5; color: var(--sw-text-color-secondary); font-size: var(--sw-font-size-small); }
.dev-affix-demo-menu .dev-affix-panel { opacity: 1; }
</style>

<div class="dev-affix-demos">
  <div class="dev-affix-demo">
    <h3>boundary-edge top</h3>
    <p>boundary — <code>.dev-affix-main</code> (нижний блок).</p>
    <div class="dev-affix-layout">
      <aside class="dev-affix-aside">
        <sw-affix :offset="20" boundary=".dev-affix-main" boundary-edge="top">
          <div class="dev-affix-panel">
            <p>Affix — первая строка.</p>
            <p>Affix — вторая строка.</p>
            <p>Affix — третья строка.</p>
          </div>
        </sw-affix>
      </aside>
      <p>Контент — строка 1.</p>
      <p>Контент — строка 2.</p>
      <p>Контент — строка 3.</p>
      <p>Контент — строка 4.</p>
      <p>Контент — строка 5.</p>
      <p>Контент — строка 6.</p>
      <p>Контент — строка 7.</p>
      <p>Контент — строка 8.</p>
      <p>Контент — строка 9.</p>
      <div class="dev-affix-main">end of content</div>
    </div>
  </div>
  <div class="dev-affix-demo dev-affix-demo-menu">
    <h3>boundary-edge bottom</h3>
    <div class="dev-affix-layout">
      <div class="dev-affix-boundary-b">
        <p>Контент — строка 1.</p>
        <p>Контент — строка 2.</p>
        <p>Контент — строка 3.</p>
        <p>Контент — строка 4.</p>
        <p>Контент — строка 5.</p>
        <p>Контент — строка 6.</p>
        <p>Контент — строка 7.</p>
        <p>Контент — строка 8.</p>
        <p>Контент — строка 9.</p>
      </div>
      <aside class="dev-affix-aside">
        <sw-affix :offset="20" :offset-bottom="20" boundary=".dev-affix-boundary-b">
          <div class="dev-affix-panel">
            <p>Affix — первая строка.</p>
            <p>Affix — вторая строка.</p>
            <p>Affix — третья строка.</p>
          </div>
        </sw-affix>
      </aside>
    </div>
  </div>
</div>

SwAlert

Функция Alert() — система всплывающих сообщений. Несколько сообщений групируются; позиция и порядок задаются параметрами placement / align.

The Alert() function shows toast messages. Multiple alerts stack; position and order are controlled by placement / align.

Свойства / Properties

Имя Тип по умолчанию Значения/Описание
class String `` Добавляет пользовательский CSS-класс к компоненту.
size String `` Размер сообщения: 'large', 'small'.
type String info 'primary', 'success', 'info', 'warning', 'danger' (алиас 'error' → danger).
message String Default message Текст сообщения.
duration Number 6000 Время отображения в миллисекундах.
placement String top Вертикаль: 'top' — старые сверху в верху экрана; 'bottom' — новые сверху у низа экрана.
align String center Горизонталь: 'left', 'center', 'right'.
before String `` Иконка в начале: имя из SVG-спрайта или URL. См. SwIcon.
after String `` Иконка в конце (закрыть): имя из спрайта или URL. См. SwIcon.
onClose Function — Колбэк после закрытия.

Слоты / Slots

Default - Текст описания или модуль / модули

#prefix - Вставка перед текстом (если не передан before)

#suffix - Вставка после текста (если не передан after)

#footer - Нижний блок (рендерится только если слот передан)

Пример использования / Example Usage

<script setup>
import { Alert } from '@studio-west/component-sw'

const TABLER = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline'
const icons = {
  star: `${TABLER}/star.svg`,
  close: `${TABLER}/x.svg`
}

let alertSeq = 0

function showAlert(type, placement = 'top', align = 'center') {
  alertSeq += 1
  Alert({
    message: `#${alertSeq} ${type} (${placement}/${align})`,
    type,
    placement,
    align,
    duration: 8000,
    before: icons.star,
    after: icons.close
  })
}
</script>

<sw-button type="info" label="info" @click="showAlert('info')" />
<sw-button type="success" label="success" @click="showAlert('success')" />
<sw-button type="warning" label="warning" @click="showAlert('warning')" />
<sw-button type="danger" label="error" @click="showAlert('error')" />

<!-- позиция: повторный клик — стек -->
<sw-button
  v-for="pos in [
    { placement: 'top', align: 'left' },
    { placement: 'top', align: 'center' },
    { placement: 'bottom', align: 'right' }
  ]"
  :key="`${pos.placement}-${pos.align}`"
  type="primary"
  :label="`${pos.placement}/${pos.align}`"
  @click="showAlert('info', pos.placement, pos.align)"
/>

SwBackTop

Кнопка «наверх» — появляется после прокрутки ниже visibilityHeight, плавный scroll to top.

Свойства / Properties

Имя Тип По умолчанию Описание
class String `` CSS-класс кнопки.
visibilityHeight Number 400 Порог scrollY для показа.
right String 2rem Отступ справа (position: fixed).
bottom String 2rem Отступ снизу.

Пример

<sw-back-top :visibility-height="300" />

SwBadge

Индикатор поверх слота: число, текст или точка (isDot).

Свойства / Properties

Имя Тип По умолчанию Описание
value Number/String `` Значение на бейдже.
max Number 99 При числе > max → {max}+.
type String danger Цвет метки.
isDot Boolean false Точка вместо текста.
showZero Boolean false Показывать 0.
hidden Boolean false Скрыть метку.
class String `` CSS-класс обёртки.

Пример

<sw-badge :value="3">
  <sw-button type="primary" label="Сообщения" />
</sw-badge>
<sw-badge :value="120" :max="99" type="warning">
  <sw-button label="Уведомления" />
</sw-badge>
<sw-badge is-dot type="danger">
  <sw-button type="info" label="Точка" />
</sw-badge>
<sw-badge value="new" type="success">
  <sw-button label="Текст" />
</sw-badge>

SwButton

Компонент SwButton представляет собой кнопку с различными настраиваемыми параметрами.

Свойства / Properties

Имя Тип по умолчанию Значения/Описание
class String sw-button Добавляет пользовательский CSS-класс к компоненту.
size String `` Размер кнопки: 'large', 'small'.
type String info Тип кнопки: 'primary', 'success', 'info', 'warning', 'danger'.
round Boolean false Делает кнопку визуально закругленной.
text Boolean false Делает кнопку визуально похожей на текст (без фона только граница).
link Boolean false Преобразует кнопку в ссылку(без фона и границ).
href String `` URL, на который будет перенаправлен пользователь при клике (если link=true).
disabled Boolean false Блокирует кнопку, делая её неактивной.
label String `` Текст кнопки (альтернатива содержимому слота).
before String `` Иконка перед текстом: имя из SVG-спрайта или URL. См. SwIcon.
after String `` Иконка после текста: имя из спрайта или URL. См. SwIcon.
prefix String `` Deprecated (удалю в major) — используйте before.
postfix String `` Deprecated (удалю в major) — используйте after.

Слоты / Slots

Default - содержимое кнопки (текст, иконки или другие элементы). Если не указано, используется label, before и after.

Пример использования / Example Usage

<script setup>
const TABLER = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline'
const icons = {
  floppy: `${TABLER}/device-floppy.svg`,
  arrow: `${TABLER}/arrow-right.svg`,
  star: `${TABLER}/star.svg`,
  chevron: `${TABLER}/chevron-down.svg`,
  search: `${TABLER}/search.svg`
}
</script>

<sw-button type="primary" label="Primary" />
<sw-button type="success" label="Success" />
<sw-button size="small" type="primary" label="Small" />
<sw-button type="primary" round label="Round" />
<sw-button type="primary" text label="Text" />
<sw-button type="primary" link label="Link" />
<sw-button type="primary" disabled label="Disabled" />
<sw-button
  type="success"
  label="Сохранить"
  :before="icons.floppy"
  :after="icons.arrow"
/>
<sw-button type="warning" :before="icons.search">Слот</sw-button>

SwButtonGroup

Компонент SwButtonGroup представляет собой группу кнопок с возможностью включения режима "Radio".

Свойства / Properties

Имя Тип по умолчанию Значения/Описание
class String sw-button Добавляет пользовательский CSS-класс к компоненту.
vertical Boolean false Вертикальное расположение кнопок.
radio Boolean false Режим "Radio" неактивные кнопки будут иметь класс 'sw-text'.
round Boolean false Делает группу кнопок визуально закругленной.

Модель / Model

model - индекс активной кнопки.

Особенности реализации

  • Автоматическое отслеживание изменений в слоте через MutationObserver
  • В режиме radio кнопки автоматически получают обработчики кликов
  • Динамическое обновление классов при изменении модели

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const buttonGroupActive = ref(0)
</script>

<sw-button-group radio v-model="buttonGroupActive">
  <sw-button type="primary" size="small">Один</sw-button>
  <sw-button type="primary">Два</sw-button>
  <sw-button type="danger">Три</sw-button>
</sw-button-group>

SwCollapse

Компонент SwCollapse представляет собой аналог тегов <details> + <summary> , но с анимацией.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
visual Boolean true Видимость

Слоты / Slots

Default - Контент для скрытия

Особенности реализации

  • Плавная анимация открытия/закрытия с использованием CSS transitions
  • Адаптивное изменение размеров при динамическом контенте

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const collapseOpen = ref(true)
</script>

<sw-button size="small" @click="collapseOpen = !collapseOpen">
  {{ collapseOpen ? 'Свернуть' : 'Развернуть' }}
</sw-button>
<sw-collapse :visual="collapseOpen">
  <p>Скрываемый контент коллапса.</p>
</sw-collapse>

SwDadata

Подсказки адреса DaData. Логика, ранее в SwSelect, вынесена сюда. Клавиатура: ↑↓, Enter, Escape; поле с clearable.

Свойства / Properties

Имя Тип По умолчанию Описание
class String `` CSS-класс.
size String large 'large' / 'small'.
placeholder String `` Placeholder.
token String `` API-ключ DaData (без токена запросы не идут).

Модель / Model

{ text, coords: [lat, lon], suggestion }

Пример

<script setup>
import { ref } from 'vue'
const geo = ref({ text: '', coords: [0, 0], suggestion: null })
const token = '192ee5dbc59f8cdd137089bbe67ba1aa0b9ec5cb'
</script>

<sw-dadata v-model="geo" :token="token" placeholder="Город, улица, дом" size="small" />

SwDatePicker

Компонент SwDatePicker представляет собой панель с календарем.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
data Object new Date() Начальные данные — диапазон (при 'solid' только 'startDate'): { firstDate, startDate, endDate, holiday: { weekend, preholiday, holiday, nowork } }. firstDate — месяц при отсутствии startDate. Deprecated в holiday (удалить в major): holidays → weekend, preholidays → preholiday.
limitation Boolean, Array false Ограничения недоступных дат. Элементы работают по-разному: только endDate — всё ≤ даты; только startDate — всё ≥ даты; оба поля — закрытый диапазон (или инвертированный, если endDate < startDate). Пример: [{ endDate: '14-04-2025' }, { startDate: '01-09-2025' }, { startDate: '30-03-2025', endDate: '14-04-2025' }].
range String solid Тип календаря: 'decades','year','range', 'solid'.

События / Events

input — событие выбора: { dateStart: "11.11.2011", dateEnd: "14.12.2011" /* при range */, count: 1 } (формат DD.MM.YYYY)

Слоты / Slots

#double-arrow - для двойной стрелки по умолчанию «

#arrow - для одинарной стрелки по умолчанию ‹

Особенности реализации

  • Поддержка множественных режимов отображения: дни, месяцы, годы, десятилетия
  • Автоматическая подсветка праздников и выходных дней
  • Интеллектуальная фильтрация недоступных дат (одиночные границы и диапазоны в limitation)
  • Даты из limitation нельзя выбрать; в режиме range нельзя выделить интервал через заблокированные дни
  • Проверка пересечения диапазонов ограничений
  • Поддержка инвертированных диапазонов (когда endDate < startDate)
  • Локализация названий месяцев и дней недели

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'

const pad = (n) => String(n).padStart(2, '0')
const fmt = (d) => `${pad(d.getDate())}-${pad(d.getMonth() + 1)}-${d.getFullYear()}`
const today = new Date()
const monthMid = new Date(today.getFullYear(), today.getMonth(), 15)
const monthEnd = new Date(today.getFullYear(), today.getMonth() + 1, 0)
const nextMonthStart = new Date(today.getFullYear(), today.getMonth() + 1, 1)

const datePickerSolid = ref({ firstDate: fmt(today) })
const datePickerRange = ref({
  firstDate: fmt(today),
  startDate: fmt(monthMid),
  endDate: fmt(new Date(today.getFullYear(), today.getMonth(), Math.min(22, monthEnd.getDate())))
})
const datePickerLimitation = ref([
  { endDate: fmt(new Date(today.getFullYear(), today.getMonth(), 3)) },
  { startDate: fmt(new Date(nextMonthStart.getFullYear(), nextMonthStart.getMonth(), 25)) },
  {
    startDate: fmt(new Date(today.getFullYear(), today.getMonth(), 10)),
    endDate: fmt(new Date(today.getFullYear(), today.getMonth(), 12))
  }
])

</script>

<!-- solid — одна дата -->
<sw-date-picker
  :data="datePickerSolid"
  :limitation="datePickerLimitation"
  range="solid"
/>

<!-- range — интервал -->
<sw-date-picker
  :data="datePickerRange"
  :limitation="datePickerLimitation"
  range="range"
/>

SwDrawer

Боковая шторка (panel/sheet). В отличие от SwMessage (центральный <dialog>), выезжает слева или справа. v-model — открыт/закрыт; Escape и клик по маске закрывают.

Свойства / Properties

Имя Тип По умолчанию Описание
class String `` Класс маски.
title String `` Заголовок (или slot #header).
placement String right 'left' / 'right'.
size String 30% Ширина панели (CSS width).
after String `` Иконка закрытия в header.
modal Boolean false Затемнение backdrop (glass + blur).
closeOnClickModal Boolean true Закрывать по клику на backdrop.

Слоты

Default — тело; #header, #footer.

Пример

<script setup>
import { ref } from 'vue'
const open = ref(false)
const close = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline/x.svg'
</script>

<sw-button type="primary" @click="open = true">Открыть</sw-button>
<sw-drawer v-model="open" title="Шторка" :after="close">
  Контент
  <template #footer>
    <sw-button size="small" @click="open = false">OK</sw-button>
  </template>
</sw-drawer>

SwDropdown

Компонент SwDropdown — всплывающее меню с настройкой места открытия и типа триггера. У попапа есть уголок, который указывает на триггер; сторона и смещение считаются по фактической позиции (с учётом flip у края экрана). z-index попапа динамический = z-index ближайшего предка + 3. Клавиатура: Escape закрывает, ↑/↓ по пунктам, Enter / Space выбирает.

Компонент с trigger="hover" и текстом/разметкой в #dropdown работает как подсказка Tooltip (без SwDropdownItem, если это не меню).

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
class String `` CSS-класс попапа (например guide для онбординга).
size String `` Размер: 'large', 'small'.
type String `` 'primary', 'success', 'info', 'warning', 'danger'.
trigger String click Способ открытия: 'click', 'hover' (в т.ч. как tooltip), 'context', 'none' — только через model.
placement String bottom-left 'bottom-left', 'bottom', 'bottom-right', 'top-left', 'top', 'top-right', 'left', 'right'.
maxWidth Number 0 Максимальная ширина меню в px. 0 — без ограничений.

Слоты / Slots

Default - текст описания или модуль / модули

#dropdown - контент всплывающего окна (пункты меню или произвольный текст для tooltip)

Модель / Model

model - состояние меню, булевое значение открыто - true

Пример использования / Example Usage

Меню:

<script setup>
import { ref } from 'vue'
const open = ref(false)
const TABLER = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline'
const star = `${TABLER}/star.svg`
const chevron = `${TABLER}/chevron-down.svg`
</script>

<sw-dropdown v-model="open" trigger="click" placement="bottom-left">
  <sw-button size="small">
    Меню <sw-icon :icon-class="chevron" />
  </sw-button>
  <template #dropdown>
    <sw-dropdown-item :before="star">Пункт со звездой</sw-dropdown-item>
    <sw-dropdown-item>Обычный пункт</sw-dropdown-item>
    <sw-dropdown-item type="danger">Опасный</sw-dropdown-item>
  </template>
</sw-dropdown>

Подсказка (tooltip):

<sw-dropdown trigger="hover" placement="top" :max-width="220">
  <sw-button label="?" type="info" />
  <template #dropdown>
    Краткая подсказка к элементу
  </template>
</sw-dropdown>

SwDropdownItem

Компонент SwDropdownItem это пункт во всплывающем меню с возможностью добавления в начало иконки.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
class String sw-dropdown-item Добавляет пользовательский CSS-класс к компоненту.
size String `` Размер поля: 'large', 'small'.
type String info 'primary', 'success', 'info', 'warning', 'danger'.
before String `` Иконка в начале: имя из спрайта или URL. См. SwIcon.
iconBefore String `` Deprecated (удалить в major) — используйте before.

Слоты / Slots

Default - текст названия или модуль

Пример использования / Example Usage

См. SwDropdown. Кратко с иконкой:

<script setup>
const star = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline/star.svg'
</script>

<sw-dropdown-item :before="star">Пункт со звездой</sw-dropdown-item>
<sw-dropdown-item>Обычный пункт</sw-dropdown-item>
<sw-dropdown-item type="danger">Пункт внимание</sw-dropdown-item>

SwFile

Компонент SwFile — загрузчик файлов с двумя режимами: photo (фото и видео с пред-просмотром и обрезкой) и document (документы с просмотром в отдельном окне браузера). Поддерживает drag & drop и выбор через системный диалог.

Режимы / Modes

Режим mode Описание / Description
Фото photo image/*, video/* — один файл, предпросмотр, обрезка области.
Документы document PDF, Word, Excel и др. — несколько файлов, клик открывает в новой вкладке.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
mode String photo 'photo' | 'document'.
disabled Boolean false Блокировка загрузки и удаления.
accept String `` Переопределение accept у <input type="file">. По умолчанию зависит от mode.
label String `` Заголовок зоны загрузки.
class String `` Дополнительный CSS-класс корневого элемента.
aspectRatio Number | null null Соотношение сторон области обрезки в режиме photo (например 1, 16/9).
editorTitle String[] см. описание Заголовки редактора: По умолчанию ['Preview', 'Preview and crop', 'Preview and crop video'].

Модель / Model

v-model — массив объектов File[] (итоговые файлы после обрезки или без неё).

События / Events

Имя Параметры Описание
change files: File[] Срабатывает при изменении списка файлов в модели.
remove file: File, index Удаление файла из списка.
preview file: File В режиме document — перед открытием в новом окне.

Слоты / Slots

Имя Описание / Description
default Текст зоны загрузки; scope: { mode, label }.
data Имя и размер файла в списке; scope: { item, file, index, size }.
remove Вся кнопка удаления; scope: { item, file, index, disabled, onClick }.
close Вся кнопка закрытия; scope: { onClick }.
skip-crop Вся кнопка без обрезки; scope: { processing, onClick }.
apply Вся кнопка применения; scope: { processing, onClick }.

Особенности реализации

Режим photo

  • После выбора файла открывается модальное окно с пред-просмотром.
  • Для изображений обрезка выполняется через canvas.
  • Для видео обрезка области записывается через canvas + MediaRecorder (результат — webm, если браузер поддерживает).
  • Область обрезки можно перемещать и менять размер угловыми ручками.
  • Кнопка skip-crop добавляет исходный файл без изменений.

Режим document

  • Файлы отображаются списком с именем и размером.
  • Можно выбрать или перетащить несколько файлов за один раз.
  • Клик по элементу открывает файл в новой вкладке.

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'

const photoFiles = ref([])
const documentFiles = ref([])
</script>

<!-- Фото / видео -->
<sw-file
  v-model="photoFiles"
  mode="photo"
  :aspect-ratio="1"
  label="Загрузить фото или видео"
  :editor-title="[
    'Предпросмотр',
    'Предпросмотр и обрезка',
    'Предпросмотр и обрезка видео'
  ]"
>
  <template #default="{ label }">
    <span class="sw-file-drop-title">{{ label }}</span>
    <span class="sw-file-drop-hint">Перетащите файл или нажмите для выбора</span>
  </template>
  <template #data="{ file, size }">
    <span class="sw-file-item-name">{{ file.name }}</span>
    <span class="sw-file-item-meta">{{ size }}</span>
  </template>
  <template #remove="{ onClick, disabled }">
    <sw-button type="danger" text :disabled="disabled" @click="onClick">Удалить</sw-button>
  </template>
  <template #skip-crop="{ onClick, processing }">
    <sw-button text :disabled="processing" @click="onClick">Без обрезки</sw-button>
  </template>
  <template #apply="{ onClick, processing }">
    <sw-button type="primary" :disabled="processing" @click="onClick">
      {{ processing ? 'Обработка…' : 'Применить' }}
    </sw-button>
  </template>
</sw-file>

<!-- Документы -->
<sw-file
  v-model="documentFiles"
  mode="document"
  label="Загрузить документы"
>
  <template #default="{ label }">
    <span class="sw-file-drop-title">{{ label }}</span>
    <span class="sw-file-drop-hint">PDF, Word, Excel — можно выбрать несколько файлов сразу</span>
  </template>
  <template #data="{ file, size }">
    <span class="sw-file-item-name">{{ file.name }}</span>
    <span class="sw-file-item-meta">{{ size }}</span>
  </template>
  <template #remove="{ onClick, disabled }">
    <sw-button type="danger" text :disabled="disabled" @click="onClick">Удалить</sw-button>
  </template>
</sw-file>

SwFormItem

Компонент SwFormItem — подписи к полям формы (не обёртка контрола): строка с подписью слева и текстом справа (подсказка / ошибка). Выравнивание через justify, цвет текста через type.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
label String `` Подпись слева.
type String `` Цвет текста: 'primary', 'success', 'info', 'warning', 'danger' ('error' → danger). Без фонов кнопок.
justify String `` Выравнивание: '' → space-between; 'start', 'end', 'around', 'center'.
class String `` Пользовательски CSS-класс корня модуля.

Слоты / Slots

#label — подпись слева (если не передан label)

Default — текст справа (подсказка / ошибка)

#before / #after — дополнительные вставки

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const formPlain = ref('')
const formOk = ref('ok')
const formBad = ref('')
</script>

<sw-form-item label="Имя">
  <sw-input v-model="formPlain" name="form-plain" label="Имя" />необязательно
</sw-form-item>
<sw-form-item label="Email" type="success">
  <sw-input v-model="formOk" name="form-ok" label="Email" />ок
</sw-form-item>
<sw-form-item label="Пароль" justify="center" type="danger">
  <sw-input v-model="formBad" name="form-bad" label="Пароль" />слишком короткий
</sw-form-item>

SwGuide

Компонент SwGuide создаёт затемнение вокруг блока по селектору и показывает SwDropdown с шагами из steps. z-index гида динамический: выше контента страницы (в т.ч. тултипов слайдера), ниже алертов.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
steps Array () => [] Массив шагов: [{ header, text, tag, placement, img }].
after String `` Иконка закрытия: имя из спрайта или URL. См. SwIcon.
iconClose String `` Deprecated (удалить в major) — используйте after.
maxWidth Number 250 Ширина всплывающего окна в px (без картинки).

Слоты / Slots

#header - заголовок окна

Default - текст сообщения с картинкой

#arrow - слот для стрелок

Модель / Model

model - массив обьектов шагов обучения

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const guideOn = ref(false)
const guideStep = ref(0)
const close = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline/x.svg'
const guideSteps = [
  { header: 'Dropdown', text: 'Клик открывает список пунктов.', tag: '#guide-demo', placement: 'bottom' },
  { header: 'Календарь', text: 'Ниже на странице — SwDatePicker.', tag: '#sw-datepicker', placement: 'bottom' }
]
</script>

<sw-button type="primary" size="small" @click="guideStep = 0; guideOn = true">Запустить гид</sw-button>
<sw-guide
  v-if="guideOn"
  v-model="guideStep"
  :steps="guideSteps"
  :after="close"
  @close="guideOn = false"
/>

SwIcon

Компонент SwIcon отображает SVG-иконку из встроенного спрайта или по-внешнему URL.

Если iconClass начинается с http://, https://, иконка загружается как внешний SVG через CSS mask (класс sw-external-icon). Иначе используется символ из спрайта: #prefix-iconClass.

Компонент используется внутри библиотеки, и во многих компонентов в props можно передавать как имя из спрайта, так и полный URL.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
iconClass String required Имя иконки в спрайте или URL (https://…).
prefix String icon Префикс символа в спрайте: #prefix-iconClass.
className String `` Пользовательский CSS-класс для элемента <svg>.

Пример использования / Example Usage

<script setup>
const TABLER = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline'
const icons = {
  star: `${TABLER}/star.svg`,
  search: `${TABLER}/search.svg`,
  phone: `${TABLER}/phone.svg`,
  chevron: `${TABLER}/chevron-down.svg`
}
</script>

<sw-icon :icon-class="icons.star" />
<sw-icon :icon-class="icons.search" />
<sw-icon :icon-class="icons.phone" />
<sw-icon :icon-class="icons.chevron" />

SwInput

Компонент SwInput представляет собой поле ввода с возможностью настройки внешнего вида и поведения.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
name String required Обязателен! нужен для связывания через id input и label.
class String sw-input Добавляет пользовательский CSS-класс к компоненту.
size String `` Размер поля: 'large', 'small'.
type String text 'text', 'phone' (маска), 'password' (кнопка показать/скрыть), 'textarea', и др. HTML-типы
inputMode String text Мобильная клавиатура: 'text', 'search', 'numeric', 'decimal', 'tel', 'url', 'email'
before String `` Иконка в начале: имя из спрайта или URL. См. SwIcon.
after String `` Иконка в конце: имя из спрайта или URL. См. SwIcon.
placeholder String `` Текст Placeholder.
required Boolean false Признак обязательно ли для заполнения.
label String `` Текст в Label.
maxlength Number 128 Параметр атрибута max-length.
minlength Number 1 Параметр атрибута min-length.
inputSize Number 60 Параметр атрибута size — ширина текстового поля.
clearable Boolean false Кнопка очистки значения.
rows Number 3 Строки для type="textarea".

Слоты / Slots

#prefix - вставка при отсутствии before не обязательно.

#suffix - вставка при отсутствии after не обязательно.

Модель / Model

model - значение поля ввода

События / Events

prefix - клик иконке before

suffix - клик иконке after

focusInput - focus на поле ввода

clear - очистка через clearable

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const inputSmall = ref('')
const inputPassword = ref('')
const inputTextarea = ref('')
const phone = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline/phone.svg'
</script>

<sw-input v-model="inputSmall" name="input-small" size="small" :before="phone" label="Small" clearable />
<sw-input v-model="inputPassword" name="input-password" type="password" label="Password" clearable />
<sw-input v-model="inputTextarea" name="input-textarea" type="textarea" label="Комментарий" :rows="4" clearable />

SwMenu

Компонент SwMenu представляет собой динамическое меню, которое генерируется на основе конфигурационного объекта или массива. Поддерживает рендеринг любых компонентов с возможностью настройки слотов и свойств.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
menuItems Object | Array required Конфигурация меню. Объект или массив объектов с компонентами и их настройками.
class String '' Добавляет пользовательский CSS-класс к компоненту.

Модель / Model

model - массив булевых значений для двусторонней привязки (v-model) с компонентами первого уровня.

События / Events

click - событие клика по компоненту. Параметры: { index, componentName, event, value }

change - событие изменения значения компонента. Параметры: { index, componentName, event?, value }

Формат конфигурации menuItems

Вариант 1: Объект
{
  'SwButton': {
    label: 'Кнопка',
    type: 'primary',
    slot: 'Текст кнопки'
  },
  'SwSwitch':
  [
    { 
      label: 'Переключатель 1',
      on: 'Вкл',
      off: 'Выкл'
    },
    { 
      label: 'Переключатель 2',
      checkbox: true
    }
  ]
}
Вариант 2: Массив
[
  { 
    'SwButton': { 
      label: 'Кнопка 1', 
      type: 'success' 
    } 
  },
  { 
    'SwInput': { 
      name: 'input1',
      placeholder: 'Введите текст',
      before: 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline/search.svg'
    } 
  }
]

Использование слотов

Для добавления контента в слоты компонентов используйте свойство slot:

{
  'SwDropdown': {
    trigger: 'click',
    'slot.dropdown': {
      'SwDropdownItem': {
        slot: 'Пункт меню'
      }
    }
  }
}

Или используйте префикс slot. для именованных слотов:

{
  'SwSection': {
    name: 'Секция',
    slot: 'Содержимое секции',
    'slot.footer': {
      'SwButton': {
        label: 'Сохранить',
        type: 'primary'
      }
    }
  }
}

Особенности реализации

  • Автоматический рендеринг компонентов на основе конфигурации
  • Поддержка вложенных компонентов через слоты
  • Двусторонняя привязка (v-model) для компонентов первого уровня
  • Эмит событий click и change для всех компонентов
  • Рекурсивная обработка конфигурации любой сложности
  • Поддержка как объектного, так и массивного формата menuItems

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const menuModel = ref([])
const menuItems = [
  { SwButton: { type: 'primary', size: 'small', slot: 'Пункт 1' } },
  { SwButton: { size: 'small', slot: 'Пункт 2' } },
  { SwSwitch: { id: 'menu-sw', name: 'menu-sw', on: 'On', off: 'Off' } }
]
</script>

<sw-menu v-model="menuModel" :menu-items="menuItems" @click="console.log" />

SwMessage

Компонент SwMessage — модальное окно по центру (<dialog>). При открытии блокирует прокрутку страницы (body.overflow = hidden).

SwMessage is a centered modal (<dialog>). While open it locks page scroll.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
name String `` Текстовый заголовок; при отсутствии — слот "header".
class String `` Пользовательский CSS-класс.
after String `` Иконка кнопки закрытия: имя из спрайта или URL. См. SwIcon.
iconAfter String `` Deprecated (удалить в major) — используйте after.

Слоты / Slots

#header - слот для заголовка окна.

Default - текст описания или модуль / модулия

#footer - слот для подвала.

Модель / Model

model - состояние компонента булевое значение, при true - окно открыто, при false - закрыто.

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const messageOpen = ref(false)
const close = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline/x.svg'
</script>

<sw-button type="primary" label="Открыть сообщение" @click="messageOpen = true" />
<sw-message v-model="messageOpen" name="Сообщение" :after="close">
  Текст диалога. Клик снаружи закрывает окно.
  <template #footer>
    <sw-button type="primary" size="small" @click="messageOpen = false">OK</sw-button>
  </template>
</sw-message>

SwPagination

Постраничная навигация. v-model — текущая страница (с 1).

Свойства / Properties

Имя Тип По умолчанию Описание
total Number 0 Всего элементов.
pageSize Number 10 Элементов на странице (v-model:page-size).
pageSizes Number[] [10, 20, 50, 100] Варианты в селекте размера.
showSize Boolean true Показать выбор «N / стр.».
pagerCount Number 7 Число кнопок страниц (нечётное).
size String `` small / large.
showTotal Boolean false Текст «Всего N».
disabled Boolean false Блок неактивен.
class String `` CSS-класс.

Модель / Events

  • v-model / modelValue — номер страницы
  • v-model:page-size — размер страницы
  • change — новая страница
  • size-change — новый размер страницы

Пример

<script setup>
import { ref } from 'vue'
const page = ref(1)
const pageSize = ref(10)
</script>

<sw-pagination
  v-model="page"
  v-model:page-size="pageSize"
  :total="240"
  :page-sizes="[10, 20, 50, 100]"
  show-total
/>

SwSection

Компонент SwSection это тег section с шаблоном из слотов, по умолчанию в слот #header добавлено заголовок и иконка.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
name String `` Добавляет заголовок в секцию.
class String sw-section Добавляет пользовательский CSS-класс к компоненту.
after String `` Иконка в заголовке: имя из спрайта или URL. См. SwIcon.
iconAfter String `` Deprecated (удалить в major) — используйте after.

Слоты / Slots

#header - слот для заголовка секции.

Default - содержимое секции

#footer - слот для подвала секции.

События / Events

header - клик по всему Header

Пример использования / Example Usage

<script setup>
const chevron = 'https://cdn.jsdelivr.net/npm/@tabler/icons@3.19.0/icons/outline/chevron-down.svg'
</script>

<sw-section name="Заголовок секции" :after="chevron" @header="console.log('section header')">
  <p>Контент секции. Клик по шапке эмитит header.</p>
  <template #footer>
    <sw-button size="small" type="primary">В футере</sw-button>
  </template>
</sw-section>

SwSelect

Универсальный выпадающий список: options, single / multiple, clearable, клавиатура (↑↓ Home/End Enter Escape).

Миграция: подсказки DaData перенесены в SwDadata (<sw-dadata>).

Свойства / Properties

Имя Тип По умолчанию Описание
class String `` CSS-класс.
size String large 'large' / 'small'.
placeholder String `` Placeholder.
options Array [] { label, value, disabled? }[].
multiple Boolean false Мультивыбор; модель — массив значений.
clearable Boolean false Кнопка очистки.
disabled Boolean false Неактивен.

Пример

<script setup>
import { ref } from 'vue'
const city = ref('')
const cities = ref([])
const options = [
  { label: 'Москва', value: 'msk' },
  { label: 'Санкт-Петербург', value: 'spb' }
]
</script>

<sw-select v-model="city" :options="options" placeholder="Город" clearable />
<sw-select v-model="cities" :options="options" multiple clearable placeholder="Несколько" />

SwSkeleton

Компонент SwSkeleton используется для анимации загрузки данных, выступая оболочкой компонента SwSkeletonItem или пользовательского компонента при использовании слота #skeleton, по умолчанию в слот #skeleton добавлен 1 SwSkeletonItem с базовыми настройками

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
class String sw-skeleton Добавляет пользовательский CSS-класс к компоненту.
visual Boolean false Тригер на переключение.

Слоты / Slots

Default - Содержимое

#skeleton - слот для skeleton

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const skeletonReady = ref(false)
</script>

<sw-button size="small" @click="skeletonReady = !skeletonReady">
  {{ skeletonReady ? 'Показать скелетон' : 'Показать контент' }}
</sw-button>
<sw-skeleton :visual="skeletonReady">
  <p>Загруженный контент.</p>
  <template #skeleton>
    <sw-skeleton-item animate width="80" />
    <sw-skeleton-item animate size="small" width="60" />
    <sw-skeleton-item animate width="40" />
  </template>
</sw-skeleton>

SwSkeletonItem

Компонент SwSkeletonItem представляет собой полоску псевдо данных с возможностью анимирования.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
width String 100 Ширина элемента в процентах.
class String sw-skeleton-item Добавляет пользовательский CSS-класс к компоненту.
animate String false Добавляет анимацию в элемент.
size String `` Размер поля: 'large', 'small'.

Пример использования / Example Usage

<sw-skeleton-item
  animate
  class="custom-class"
  size="small"
  width="60"
 />

SwSlider

Компонент SwSlider — слайдер с одним или несколькими ползунками: число в v-model → 1 бегунок, массив из n чисел → n бегунков. Значения в массиве сортируются при перетаскивании; тултип следует за тянущимся ползунком при перескоке. Без CSS-lag на left/top во время drag.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
vertical Boolean false Вертикальная ориентация (min снизу, max сверху).
class String `` Пользовательский CSS-класс.
size String `` Размер бегунка: 'large', 'small'.
min Number 0 Минимум.
max Number 100 Максимум.
step Number 1 Шаг.
show-value Boolean false Всплывающее значение при наведении / drag.
track-color Array [] Цвета сегментов трека между thumb; пустой — --sw-color-primary.

Сегменты: число — 0 → thumb; массив — thumb₀ → thumb₁. Если цветов меньше — последний повторяется.

Слоты / Slots

Default - содержимое бегунка (index, value в слот-пропсах).

Модель / Model

v-model — Number или Number[]

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const sliderValue = ref(40)
const sliderMulti = ref([15, 35, 60, 85])
</script>

<sw-slider v-model="sliderValue" :min="0" :max="100" show-value />
<sw-slider
  v-model="sliderMulti"
  :min="0"
  :max="100"
  show-value
  :track-color="['var(--sw-color-success)', 'var(--sw-color-warning)', 'var(--sw-color-danger)']"
/>

SwSwitch

Компонент SwSwitch представляет собой чекбокс с возможностью настройки внешнего вида галочка | переключатель | переключатель с подписью и поведения.

Свойства / Properties

Имя Тип По умолчанию Значения/Описание
name String `` Добавляет в атрибут 'name'.
class String sw-switch Добавляет пользовательский CSS-класс к компоненту.
size String `` Размер поля: 'large', 'small'.
id String checkbox Добавляет в атрибут 'id'.
on String `` Текст при true.
off String `` Текст при false.
checkbox Boolean false Визуализирует как обычный чекбокс.

Слоты / Slots

Default - текст описания

Модель / Model

model - состояние чекбокса (checked ) булевое значение

Пример использования / Example Usage

<script setup>
import { ref } from 'vue'
const switchOn = ref(true)
const switchCheck = ref(false)
</script>

<sw-switch v-model="switchOn" id="sw-demo-1" name="sw-demo-1" on="Вкл" off="Выкл">С подписями</sw-switch>
<sw-switch v-model="switchCheck" id="sw-demo-2" name="sw-demo-2" checkbox>checkbox</sw-switch>

SwTable

Компонент SwTable — динамическая таблица с вложенными заголовками, объединением ячеек (rowspan / colspan), кастомизацией через слоты, подсветкой строк и столбцов при наведении, изменением ширины колонок и фиксацией крайних колонок при горизонтальном скролле.

Колонки описываются дочерним компонентом SwTableColumn.

Свойства SwTable / SwTable Properties

Имя Тип По умолчанию Значения/Описание
data Array required Данные таблицы — массив объектов.
resizable Boolean true Разрешить изменение ширины колонок перетаскиванием края заголовка.
maxWidth String | Number — Максимальная ширина контейнера таблицы. При переполнении — горизонтальный скролл и активация fixed-колонок.

События SwTable / SwTable Events

Имя Параметрыd Описание
column-resize { prop, width } Срабатывает после изменения ширины колонки (в px).

Свойства SwTableColumn / SwTableColumn Properties

Имя Тип По умолчанию Значения / Описание
prop String — Ключ поля в объекте строки. Поддерживает вложенные пути: speed.midl.
label String '' Заголовок колонки.
width String | Number 'auto' Ширина колонки, например 180 или '180px'.
height String | Number 'auto' Минимальная высота ячейки заголовка.
resizable Boolean — Разрешить ресайз конкретной колонки. По умолчанию наследует resizable таблицы.
minWidth String | Number 48 Минимальная ширина при ресайзе (px).
fixed String — 'left' | 'right' — фиксация колонки при горизонтальном скролле.

SwTableColumn без prop используется как групповой заголовок; внутри него задаются дочерние SwTableColumn.

Подсветка при наведении / Hover highlight

  • Row — при наведении на строку в tbody подсвечиваются все её ячейки (учитывается rowspan).
  • Column — при наведении на ячейку заголовка подсвечивается весь столбец; для группового заголовка с colspan — все вложенные колонки.

Стили подсветки заданы в component-sw.css (классы row-hover, col-hover).

Фиксированные колонки / Fixed columns

Фиксация включается, когда одновременно:

  1. задан max-width у SwTable;
  2. у колонок указан fixed="left" или fixed="right";
  3. суммарная ширина таблицы превышает контейнер.

Групповой заголовок фиксируется, если все его дочерние колонки имеют одинаковое значение fixed.

Слоты / Slots

#<prop> — именованный слот для конкретной колонки (приоритет выше cell). Параметры: { row, $index, value }

#cell — универсальный слот для всех колонок (default-слот занят SwTableColumn). Параметры: { row, $index, column, value }

  • row — весь объект строки данных
  • $index — индекс строки (начиная с 0)
  • column — имя колонки (prop)
  • value — значение ячейки

Пример использования / Example Usage

Базовая таблица с ресайзом и слотами:
<script setup>
import { ref } from 'vue'
const users = ref([
  { name: 'Иван Петров', age: 25, status: 'active' },
  { name: 'Мария Сидорова', age: 30, status: 'inactive' },
  { name: 'Петр Иванов', age: 35, status: 'active' }
])
function logRow(row) {
  console.log('row:', row)
}
</script>

<sw-table :data="users" :

Related Packages

vue-svg-pan-zoom

Vue component for svg-pan-zoom

59,567
@jt-icons/icon-vue-components

Vue components of JT Icons collection.

2,961 1
@svgv/core

Node.js API to transform SVGs into Vue components.

1,525 4
@k-l-lambda/web-widgets

A package contains some utility vue.js components and modules.

831 0
svg-to-vue

Utility to convert SVG code into Vue component definition

2,667,077 31

Version History

Version Released License
1.0.3 ISC
1.0.2 ISC
1.0.1 ISC
1.0.0 ISC
0.13.19 ISC