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

@studio-west/component-sw

v1.0.3

Published

Vue components of Component-SW collection.

Readme

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](#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/[email protected]/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](#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/[email protected]/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/[email protected]/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/[email protected]/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/[email protected]/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](#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/[email protected]/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/[email protected]/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](#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/[email protected]/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/[email protected]/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](#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/[email protected]/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/[email protected]/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" :