@1337exp/taoui 1.0.2 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -11,9 +11,11 @@
11
11
  - **TaoButton** — кнопка с вариантами (primary, secondary, ghost, danger), размерами и состояниями
12
12
  - **TaoCard** — карточка с поддержкой слотов (cover, headerTitle, header/headerSecondary, title/sub, footer)
13
13
  - **TaoCopy** — кнопка копирования текста в буфер обмена
14
- - **TaoInput** — поле ввода с поддержкой v-model, валидации и различных типов
14
+ - **TaoInput** — поле ввода с поддержкой v-model, валидации и слотов `#prefix` / `#suffix` (иконка или текст внутри рамки)
15
+ - **TaoInputGroup** — склейка снаружи: `#before` | поле | `#after` (протокол, единица, кнопка)
15
16
  - **TaoModal** — модальное окно с анимацией и слотами
16
- - **TaoSpoiler** — раскрывающийся блок (аккордеон)
17
+ - **TaoDrawer** — боковая панель (фильтры, настройки). Esc, клик по фону, ловушка фокуса — как у модалки
18
+ - **TaoSpoiler** — раскрывающийся блок. `v-model` и `aria-expanded`; несколько подряд — не exclusive-аккордеон
17
19
  - **TaoTabs** — вкладки для переключения между секциями контента
18
20
  - **TaoTooltip** — всплывающая подсказка при наведении
19
21
 
@@ -22,21 +24,37 @@
22
24
  - **TaoContainer** — контейнер с ограничением ширины (wide/slim/ultra-slim) и авто-центровкой
23
25
  - **TaoFlex** — обёртка над flexbox с пропами justify/align/direction/wrap/gap
24
26
  - **TaoSpace** — авто-расстановка дочерних элементов с равномерным gap
25
- - **TaoDivider** — разделитель: line (тонкая линия), text (линия с текстом), gap (пустой отступ)
27
+ - **TaoDivider** — разделитель: line (тонкая линия), text (линия с текстом), gap (пустой отступ, size: small/medium/large)
26
28
  - **TaoAnimatedBorder** — контейнер с анимированной радужной рамкой (декоративный, не завязан на тему)
27
29
 
28
30
  ### Формы и ввод
29
31
 
30
- - **TaoCheckbox** — чекбокс с поддержкой v-model и слотов pre/post
31
- - **TaoTextarea** — многострочное поле с авто-высотой и модификаторами (noBorder, noBackground, textCenter, submitOnEnter)
32
- - **TaoPinCode** — пин-код из N полей с авто-переходом фокуса между ними
33
- - **TaoSlider** — интерактивный слайдер (drag + клик), с опциональным точным вводом значения по правому клику
34
- - **TaoFileDrop** — зона загрузки файлов (drag & drop + клик)
32
+ - **TaoCheckbox** — чекбокс с v-model, слотами pre/post и `indeterminate` (частично выбран)
33
+ - **TaoSwitch** — переключатель для булевых настроек (`role="switch"`)
34
+ - **TaoRadio** / **TaoRadioGroup** — взаимоисключающий выбор из 2–5 вариантов
35
+ - **TaoSelect** — выпадающий список с клавиатурой, тот же визуал, что у Input. Сброс — «Очистить» в списке или Delete
36
+ - **TaoDate** — один день: `YYYY-MM-DD`, без часов и пояса. Календарь как у Select
37
+ - **TaoFormField** — общие label / hint / error для полей формы
38
+ - **TaoInputNumber** — число с min/max/step и кнопками ± справа. Пустое значение — `null`
39
+ - **TaoQuantity** — количество в корзине: `− | поле | +`, целые штуки, сток, минус на минимуме может убрать строку
40
+ - **TaoTextarea** — многострочное поле с авто-высотой. `maxlength` ограничивает ввод, `count` показывает «введено / максимум»
41
+ - **TaoPinCode** — пин-код из N полей. По умолчанию клик стирает ячейку и все справа (`clear-on="focus"`); `clear-on="input"` заменяет цифру только при вводе. Последняя ячейка снимает фокус и эмитит `complete`
42
+ - **TaoSlider** — слайдер: мышь, тач и стрелки. Опциональный точный ввод по правому клику
43
+ - **TaoFileDrop** — зона загрузки файлов (drag & drop + клик). Текст внутри — слот
35
44
 
36
45
  ### Отображение данных
37
46
 
38
- - **TaoTag** — тег/бейдж со статусами (neutral, success, danger)
39
- - **TaoProgress** — статичная полоса прогресса, опционально с shimmer-анимацией
47
+ - **TaoTable** — простая таблица: колонки, empty, loading, сортировка через `v-model:sort`. Не datagrid.
48
+ - **TaoPagination** — страницы с многоточием. Клик по «…» прыгает на `jump` страниц (5 по умолчанию)
49
+ - **TaoEmpty** — пустой список, нет результатов, нет прав
50
+ - **TaoStages** — список стадий: `wait` / `work` / `ok` / `bad`. Не линейный степпер
51
+ - **TaoSkeleton** — плейсхолдер загрузки (text / title / circle / rect)
52
+ - **TaoCounter** — витрина числа с переворотом цифр (не инпут)
53
+ - **TaoCarousel** — лента: целый слайд с `autoplay`, карточка с `peek`, полоса с `per-view`. Стрелки через `controls` или `#prev` / `#next`, точки — `dots`
54
+ - **TaoAvatar** — фото или инициалы, размеры `small` / `medium` / `large`. Точка `dot` и счётчик `count`
55
+ - **TaoTag** — тег/бейдж со статусами (neutral, success, danger, warning, info)
56
+ - **TaoAlert** — инлайн-баннер страницы или ошибки формы (success / error / warning / info)
57
+ - **TaoProgress** — статичная полоса (`progress` в %). Проценты сверху по центру или `showPercentage="right"` справа; слоты `#left` / `#right` — подписи, тогда процент справа в скобках. `false` прячет. Ширина — `minWidth` / `maxWidth`, не диапазон значения
40
58
  - **TaoLoader** — анимированный лоадер (четыре точки)
41
59
  - **TaoImage** — обёртка над `<img>` с плавным fade-in при загрузке и плейсхолдером
42
60
  - **TaoIcon** — обёртка для icon-шрифта (см. раздел «Иконки» ниже)
@@ -44,8 +62,25 @@
44
62
  ### Навигация и взаимодействие
45
63
 
46
64
  - **TaoLink** — ссылка, использующая `<NuxtLink>` в Nuxt-проекте и обычный `<a>` вне его — без дополнительной настройки
65
+ - **TaoBreadcrumb** — крошки: последний пункт — текущая страница
47
66
  - **TaoDropdownMenu** — выпадающее меню с авто-позиционированием у края экрана
48
- - **TaoScrollTop** — плавающая кнопка «наверх» с ripple-эффектом, появляется при обратном скролле
67
+ - **TaoScrollTop** — плавающая кнопка «наверх» с ripple. Появляется при обратном скролле после `boundary`
68
+
69
+ ### Обратная связь
70
+
71
+ - **toast()** — fluent-уведомления: `toast().success().message('Сохранено')`
72
+ - **confirm()** — вопрос с оверлеем: тот же fluent + `await`. Не тост — ждёт ответ, не исчезает сам.
73
+ - **TaoToastViewport** / **TaoConfirmHost** — контейнеры; если их нет в разметке, первый вызов сам монтирует их в `body`
74
+
75
+ ## Соглашения
76
+
77
+ Тоны визуала: `success` | `danger` | `warning` | `info` | `neutral`.
78
+ `error` у Alert, Tag и `toast()` — синоним `danger`. Button уже `danger`.
79
+ Stages — это процесс, не тон: `wait` / `work` / `ok` / `bad` (`danger` принимается как `bad`).
80
+
81
+ Размеры контролов: `small` | `medium` | `large`.
82
+ Avatar понимает и короткие `s` / `m` / `l`. Divider `gap` раньше называл крупный размер `big` — это алиас `large`.
83
+ Container живёт на другой оси: `wide` / `slim` / `ultra-slim`.
49
84
 
50
85
  ## Иконки
51
86
 
@@ -116,6 +151,192 @@ import '@1337exp/taoui/styles.css'
116
151
  </template>
117
152
  ```
118
153
 
154
+ ## Toast
155
+
156
+ Вызов — цепочка в одном тике, `setTimeout(0)` отправляет уведомление.
157
+
158
+ ```javascript
159
+ import { toast } from '@1337exp/taoui'
160
+
161
+ toast().success().message('Сохранено')
162
+ toast().error().title('Сеть').timeout(5000).message('Нет соединения')
163
+ toast.success('Сохранено')
164
+ toast.warning('Черновик', { timeout: 1000 })
165
+ ```
166
+
167
+ Позиция по умолчанию — `topCenter`. Глобально:
168
+
169
+ ```javascript
170
+ toast.defaults({ position: 'bottomRight' })
171
+ toast.byBottomRight()
172
+ ```
173
+
174
+ `question` с оверлеем в kit нет — это confirm, не toast. Кнопки в тосте, если нужны:
175
+
176
+ ```javascript
177
+ toast().info().message('Удалить файл?').action('Удалить', onRemove)
178
+ ```
179
+
180
+ Viewport можно не вставлять: первый вызов сам создаст его. Если нужен явный контроль (тесты, свой layout):
181
+
182
+ ```vue
183
+ <TaoToastViewport />
184
+ ```
185
+
186
+ ## Confirm
187
+
188
+ Вопрос с оверлеем: всплывает по центру и спрашивает. Это не toast — нет прогресс-бара и автозакрытия, есть `await`, Esc и клик по оверлею = отмена.
189
+
190
+ ```javascript
191
+ import { confirm } from '@1337exp/taoui'
192
+
193
+ if (await confirm().title('Удалить файл?').message('Это нельзя отменить').danger()) {
194
+ remove()
195
+ }
196
+
197
+ const ok = await confirm('Выйти без сохранения?', {
198
+ ok: 'Выйти',
199
+ cancel: 'Остаться',
200
+ })
201
+ ```
202
+
203
+ Очередь: второй `confirm()`, пока открыт первый, подождёт. Подписи по умолчанию — «ОК» / «Отмена»:
204
+
205
+ ```javascript
206
+ confirm.defaults({ ok: 'Yes', cancel: 'No' })
207
+ ```
208
+
209
+ ## Формы
210
+
211
+ `TaoFormField` вешает общий label / hint / error и прокидывает `id` во вложенный контрол.
212
+
213
+ ```vue
214
+ <TaoFormField label="Город" hint="Необязательно">
215
+ <TaoSelect v-model="city" :options="cities" />
216
+ </TaoFormField>
217
+
218
+ <TaoSwitch v-model="dark" label="Тёмная тема" />
219
+
220
+ <TaoRadioGroup v-model="plan" legend="Тариф">
221
+ <TaoRadio value="free" label="Free" />
222
+ <TaoRadio value="pro" label="Pro" />
223
+ </TaoRadioGroup>
224
+
225
+ <TaoAlert type="warning" title="Черновик">Сохраните, прежде чем уйти.</TaoAlert>
226
+ ```
227
+
228
+ `TaoSelect` открывается с клавиатуры (стрелки, Enter, Esc), список переворачивается у края экрана. Delete или «Очистить» внизу списка сбрасывает значение в `null`.
229
+
230
+ `TaoFormField` также оборачивает `TaoTextarea` и `TaoCheckbox` — id, hint и error прокидываются сами.
231
+
232
+ ## Таблица и пагинация
233
+
234
+ Таблица рендерит то, что передали: сама данные не режет и не сортирует. Это удобно и для серверной выборки, и для клиентской — страница режется снаружи.
235
+
236
+ ```vue
237
+ <TaoTable
238
+ :columns="columns"
239
+ :rows="pageRows"
240
+ v-model:sort="sort"
241
+ empty-text="Пока нет записей"
242
+ >
243
+ <template #cell-status="{ row }">
244
+ <TaoTag :type="row.status === 'active' ? 'success' : 'neutral'">
245
+ {{ row.status }}
246
+ </TaoTag>
247
+ </template>
248
+ </TaoTable>
249
+
250
+ <TaoPagination v-model:page="page" :total="rows.length" :page-size="8" />
251
+ ```
252
+
253
+ ```javascript
254
+ const columns = [
255
+ { key: 'name', label: 'Имя', sortable: true },
256
+ { key: 'city', label: 'Город' },
257
+ { key: 'status', label: 'Статус' },
258
+ ]
259
+ ```
260
+
261
+ Слот `cell-<ключ>` перекрывает ячейку. `loading` показывает оверлей, пустой список — текст или слот `#empty`. Клик по шапке с `sortable` крутит `asc → desc → сброс`.
262
+
263
+ ## Пустые состояния и загрузка
264
+
265
+ ```vue
266
+ <TaoEmpty title="Ничего не нашлось">
267
+ Измените фильтр или сбросьте поиск.
268
+ <template #action>
269
+ <TaoButton variant="secondary">Сбросить</TaoButton>
270
+ </template>
271
+ </TaoEmpty>
272
+
273
+ <TaoSkeleton variant="title" />
274
+ <TaoSkeleton :lines="3" />
275
+ <TaoSkeleton variant="circle" />
276
+
277
+ <TaoStages :items="[
278
+ { key: 'pay', label: 'Оплата', status: 'ok' },
279
+ { key: 'pack', label: 'Сборка', status: 'work' },
280
+ { key: 'ship', label: 'Доставка', status: 'wait' },
281
+ ]" />
282
+ ```
283
+
284
+ ```vue
285
+ <TaoInput v-model="q" placeholder="Найти…">
286
+ <template #prefix>⌕</template>
287
+ </TaoInput>
288
+
289
+ <TaoInputGroup>
290
+ <template #before>https://</template>
291
+ <TaoInput v-model="host" placeholder="example.com" />
292
+ <template #after>
293
+ <TaoButton>Проверить</TaoButton>
294
+ </template>
295
+ </TaoInputGroup>
296
+
297
+ <form @submit.prevent="onSave">
298
+ <TaoFormField label="Email">
299
+ <TaoInput v-model="email" type="email" />
300
+ </TaoFormField>
301
+ <TaoButton type="submit">Сохранить</TaoButton>
302
+ </form>
303
+
304
+ <TaoFormField label="Количество">
305
+ <TaoInputNumber v-model="qty" :min="1" :max="99" />
306
+ </TaoFormField>
307
+
308
+ <TaoQuantity v-model="qty" :max="12" @dec="onDec" />
309
+
310
+ <TaoFormField label="День доставки" hint="В модели всегда YYYY-MM-DD">
311
+ <TaoDate v-model="day" min="2026-09-01" max="2026-09-30" />
312
+ </TaoFormField>
313
+
314
+ <TaoCounter :value="score" :max-digits="6" />
315
+
316
+ <TaoCarousel :autoplay="4000" loop dots>
317
+ <article v-for="item in banners" :key="item.id" class="hero">
318
+ <strong>{{ item.title }}</strong>
319
+ <span>{{ item.text }}</span>
320
+ </article>
321
+ </TaoCarousel>
322
+ <TaoCarousel :peek="72" :controls="false" dots>…</TaoCarousel>
323
+ <TaoCarousel v-model="slide" :per-view="5" :peek="28">
324
+ <template #prev></template>
325
+ <template #next="{ go, disabled }">
326
+ <button type="button" :disabled="disabled" @click="go">вперёд</button>
327
+ </template>
328
+ <article v-for="item in products" :key="item.id">…</article>
329
+ </TaoCarousel>
330
+ ```
331
+
332
+ `TaoDrawer` — лист сбоку, не модалка по центру:
333
+
334
+ ```vue
335
+ <TaoDrawer v-model="open" title="Фильтры">
336
+ ...
337
+ </TaoDrawer>
338
+ ```
339
+
119
340
  ## Дизайн-токены и темизация
120
341
 
121
342
  Стили библиотеки построены в три слоя. Компоненты **никогда** не обращаются
@@ -179,10 +400,12 @@ document.documentElement.setAttribute('data-tao-theme', 'light')
179
400
  ### Ключевые группы токенов
180
401
 
181
402
  - `--tao-color-accent*` — акцентный/брендовый цвет (кнопки primary, активные вкладки, ссылки)
403
+ - `--tao-color-on-accent` — текст на акцентном фоне (`--tao-color-text-on-accent` — алиас)
404
+ - `--tao-color-selection`, `--tao-color-selection-text` — выделение текста (`::selection`)
182
405
  - `--tao-color-surface*` — фоны контейнеров (обычный / приподнятый / утопленный / hover)
183
406
  - `--tao-color-border*` — границы
184
407
  - `--tao-color-text*` — текст (обычный / усиленный / приглушённый / disabled)
185
- - `--tao-color-danger*`, `--tao-color-success*` — статусные цвета
408
+ - `--tao-color-danger*`, `--tao-color-success*`, `--tao-color-warning*`, `--tao-color-info*` — статусные цвета
186
409
  - `--tao-color-input-*` — поля ввода отдельно, т.к. фон/текст полей часто не совпадают с surface/text
187
410
  - `--tao-radius-control`, `--tao-radius-panel` — скругления (мелкие контролы vs крупные панели)
188
411
  - `--tao-shadow-panel`, `--tao-shadow-overlay` — тени
@@ -211,6 +434,10 @@ npm run dev
211
434
  В showcase есть переключатель темы (dark / light) в шапке — так виден
212
435
  эффект переопределения токенов без правок кода компонентов.
213
436
 
437
+ Showcase смотрит прямо в `src/`, поэтому правки компонентов видны без
438
+ `npm run build`. Сборка `dist/` нужна для публикации и для чужих проектов,
439
+ которые ставят пакет.
440
+
214
441
  ## Разработка
215
442
 
216
443
  ```bash