@boobooking/dashboard-ui-components 0.19.0 → 0.20.0
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 +323 -87
- package/dist/index.js +973 -517
- package/dist/style.css +1 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
npm install @boobooking/dashboard-ui-components
|
|
8
8
|
|
|
9
9
|
```js
|
|
10
|
-
import { RussianMobileFilter,
|
|
10
|
+
import { RussianMobileFilter, SelectDateIntervalFilter } from '@boobooking/dashboard-ui-components'
|
|
11
11
|
import '@boobooking/dashboard-ui-components/style.css'
|
|
12
12
|
```
|
|
13
13
|
|
|
@@ -65,10 +65,12 @@ Vue не ниже 3.5, ESM, сборщик, умеющий импорт CSS из
|
|
|
65
65
|
Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в CSS приложения
|
|
66
66
|
пакету не нужны.
|
|
67
67
|
|
|
68
|
-
Меню `DropdownButtonWithAction` и `HamburgerMenu`, списки `
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
Меню `DropdownButtonWithAction` и `HamburgerMenu`, списки `SelectSingleFilter`,
|
|
69
|
+
`SelectSingleForm`, `SelectMultipleFilter` и `SelectMultipleForm`, календари
|
|
70
|
+
`SelectDateFilter`, `SelectDateForm`, `SelectDateIntervalFilter`,
|
|
71
|
+
`SelectDateIntervalForm` и подсказка `TextPopover`
|
|
72
|
+
стоят на Popover API браузера: Safari 17+, Chrome 114+, Firefox 125+. В браузерах
|
|
73
|
+
старше меню, списки, календари и подсказка видны в потоке всегда.
|
|
72
74
|
|
|
73
75
|
## Цвета
|
|
74
76
|
|
|
@@ -82,7 +84,7 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
82
84
|
| --- | --- |
|
|
83
85
|
| `InfoPill`, `ActionPill` | фон `-100`, текст `-800`; у `ActionPill` при наведении текст `-600` |
|
|
84
86
|
| основная кнопка и стрелка `DropdownButtonWithAction` | фон `-100`, рамка `-300`, текст `-800`, при наведении фон `-200` |
|
|
85
|
-
| пункт меню `DropdownButtonWithAction` и `HamburgerMenu` | текст `-800`, в фокусе фон `-
|
|
87
|
+
| пункт меню `DropdownButtonWithAction` и `HamburgerMenu` | фон `-100`, текст `-800`, при наведении и в фокусе фон `-200` |
|
|
86
88
|
| `Dot`, полоска строки `DataTable` | `-500` |
|
|
87
89
|
|
|
88
90
|
Без цвета кнопка белая с серой рамкой, пункт меню серый, строка таблицы без
|
|
@@ -90,10 +92,12 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
90
92
|
|
|
91
93
|
## Компоненты
|
|
92
94
|
|
|
93
|
-
Пакет экспортирует
|
|
94
|
-
`Search`, `
|
|
95
|
-
`
|
|
96
|
-
`
|
|
95
|
+
Пакет экспортирует двадцать четыре компонента: `Dot`, `RussianMobileFilter`,
|
|
96
|
+
`Search`, `SelectDateFilter`, `SelectDateForm`, `SelectDateIntervalFilter`,
|
|
97
|
+
`SelectDateIntervalForm`,
|
|
98
|
+
`SelectSingleFilter`, `SelectSingleForm`, `SelectMultipleFilter`,
|
|
99
|
+
`SelectMultipleForm`, `InfoPill`, `ErrorMessages`, `FormInput`, `ActionPill`,
|
|
100
|
+
`ConfirmationModal`, `DropdownButtonWithAction`, `HamburgerMenu`, `DataTable`,
|
|
97
101
|
`NavigationMenuElement`, `PageTabs`, `PageCard`, `NotificationMessage`,
|
|
98
102
|
`TextPopover`, функцию `downloadFile` и плагин `dashboardUi`. В архив пакета
|
|
99
103
|
(`files: ["dist"]`) исходники не попадают, поэтому контракт каждого
|
|
@@ -225,14 +229,77 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
225
229
|
`isRequired` только показывает точку: атрибут `required` и `aria-*` полю
|
|
226
230
|
он не ставит.
|
|
227
231
|
|
|
228
|
-
###
|
|
232
|
+
### SelectDateFilter
|
|
233
|
+
|
|
234
|
+
Одно поле даты под заголовком. Дата выбирается в календаре Pikaday,
|
|
235
|
+
у поля — ластик очистки. Подсказки у поля нет. Pikaday загружается
|
|
236
|
+
в браузере при монтировании компонента, а не при загрузке пакета, поэтому
|
|
237
|
+
календарь появляется, когда загрузка закончится.
|
|
238
|
+
|
|
239
|
+
Высота 4.5rem и серая рамка встроены в фильтр, ширина поля 9rem: класс
|
|
240
|
+
`h-18 border border-gray-200` ему не нужен. `class` и остальные атрибуты
|
|
241
|
+
ложатся на корень фильтра.
|
|
242
|
+
|
|
243
|
+
<select-date-filter header="Дата" v-model="day" @changed="reload"/>
|
|
244
|
+
|
|
245
|
+
| Проп | Тип | По умолчанию | Описание |
|
|
246
|
+
| --- | --- | --- | --- |
|
|
247
|
+
| `modelValue` | `String` | `""` | Выбранная дата |
|
|
248
|
+
| `header` | `String` | обязателен | Подпись поля |
|
|
249
|
+
| `isRequired` | `Boolean` | `false` | Пометка обязательности в заголовке |
|
|
250
|
+
| `isLoading` | `Boolean` | `false` | Индикатор загрузки в заголовке |
|
|
251
|
+
| `lang` | `String` | язык плагина | `"ru"` или `"en"`; действует на календарь и на подпись ластика для скринридера (у самого поля текста нет) |
|
|
252
|
+
|
|
253
|
+
События: `update:modelValue` (дата или пустая строка после ластика)
|
|
254
|
+
и `changed` приходят на каждый выбор пользователя: в том числе на повторный
|
|
255
|
+
выбор уже показанной даты, на набранную в поле дату, которая разобралась,
|
|
256
|
+
и на очистку ластиком. Когда значение меняет родитель, ни одно из событий
|
|
257
|
+
не приходит. Поля диапазона `SelectDateIntervalFilter` и
|
|
258
|
+
`SelectDateIntervalForm` устроены иначе: их `changed` приходит, только когда
|
|
259
|
+
новое значение отличается от переданного пропса.
|
|
260
|
+
|
|
261
|
+
Календарь, ластик и клавиатура — как у каждого из двух полей
|
|
262
|
+
`SelectDateIntervalFilter` (см. «SelectDateIntervalFilter»).
|
|
263
|
+
|
|
264
|
+
### SelectDateForm
|
|
265
|
+
|
|
266
|
+
Одно поле даты в форме, в виде `FormInput`: подпись над полем, рамка поля
|
|
267
|
+
на всю ширину формы, высотой 38px, как у `FormInput`. Рамка скругляет и поле,
|
|
268
|
+
и кольцо фокуса в нём. Подсказки у поля нет.
|
|
269
|
+
|
|
270
|
+
<select-date-form label="Дата" v-model="day" :is-required="markDayRequired"/>
|
|
271
|
+
|
|
272
|
+
| Проп | Тип | По умолчанию | Описание |
|
|
273
|
+
| --- | --- | --- | --- |
|
|
274
|
+
| `modelValue` | `String` | `""` | Выбранная дата |
|
|
275
|
+
| `label` | `String` | обязателен | Подпись над полем |
|
|
276
|
+
| `isRequired` | `Boolean` | `false` | Красная точка у подписи |
|
|
277
|
+
| `lang` | `String` | язык плагина | `"ru"` или `"en"`; действует на календарь и на подпись ластика для скринридера (у самого поля текста нет) |
|
|
278
|
+
|
|
279
|
+
События: `update:modelValue` и `changed` — когда значение выбрал пользователь,
|
|
280
|
+
как у `SelectDateFilter` (см. «SelectDateFilter»); смена значения родителем
|
|
281
|
+
их не вызывает. Календарь, ластик и клавиатура — тоже как у него.
|
|
282
|
+
|
|
283
|
+
Подпись связана с полем для скринридера: кнопка календаря называется
|
|
284
|
+
подписью и датой, поле ввода — подписью. Клик по подписи ничего не делает.
|
|
285
|
+
|
|
286
|
+
`isRequired` только показывает точку, как у `FormInput`. `class`, `style`,
|
|
287
|
+
все остальные атрибуты и слушатели ложатся на корень компонента (у `FormInput`
|
|
288
|
+
остальные атрибуты уходят на поле ввода).
|
|
289
|
+
|
|
290
|
+
### SelectDateIntervalFilter
|
|
229
291
|
|
|
230
292
|
Два поля даты под одним заголовком — интервал дат «от» и «до». Дата
|
|
231
293
|
выбирается в календаре Pikaday, у каждого поля — ластик очистки. Pikaday
|
|
232
294
|
загружается в браузере при монтировании компонента, а не при загрузке
|
|
233
295
|
пакета, поэтому календари появляются, когда загрузка закончится.
|
|
234
296
|
|
|
235
|
-
|
|
297
|
+
Высота 4.5rem и серая рамка встроены в фильтр: класс
|
|
298
|
+
`h-18 border border-gray-200` ему не нужен. Ширина фильтра 18rem, «от» и «до»
|
|
299
|
+
по половине, между ними вертикальная линия. `class` и остальные атрибуты
|
|
300
|
+
ложатся на корень фильтра.
|
|
301
|
+
|
|
302
|
+
<select-date-interval-filter
|
|
236
303
|
header="Период"
|
|
237
304
|
:date-from="dateFrom"
|
|
238
305
|
:date-to="dateTo"
|
|
@@ -253,7 +320,8 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
253
320
|
События: `update:dateFrom`, `update:dateTo` — на каждый выбор даты
|
|
254
321
|
в соответствующем поле и на его очистку ластиком (пустой строкой);
|
|
255
322
|
`changed` — когда новое значение отличается от переданного пропса
|
|
256
|
-
(отдельно для каждой из двух дат).
|
|
323
|
+
(отдельно для каждой из двух дат). Повторный выбор уже показанной даты
|
|
324
|
+
событий не вызывает.
|
|
257
325
|
|
|
258
326
|
Клик по любому месту поля открывает его календарь. Календарь открывается
|
|
259
327
|
в верхнем слое браузера (Popover API): его не обрезает обёртка
|
|
@@ -274,9 +342,42 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
274
342
|
же, как клик; Escape закрывает календарь. После закрытия фокус возвращается на
|
|
275
343
|
поле. В поле можно перейти Tab и набрать дату.
|
|
276
344
|
|
|
277
|
-
###
|
|
345
|
+
### SelectDateIntervalForm
|
|
346
|
+
|
|
347
|
+
Интервал дат в форме, в виде `FormInput`: подпись над полями, под ней «от»
|
|
348
|
+
и «до» одинаковой ширины на всю ширину формы. У каждого поля своя рамка, как
|
|
349
|
+
у `FormInput`, высотой 38px; рамка скругляет и поле, и кольцо фокуса в нём.
|
|
350
|
+
|
|
351
|
+
<select-date-interval-form
|
|
352
|
+
label="Период"
|
|
353
|
+
v-model:date-from="dateFrom"
|
|
354
|
+
v-model:date-to="dateTo"
|
|
355
|
+
:is-required="markPeriodRequired"
|
|
356
|
+
/>
|
|
357
|
+
|
|
358
|
+
| Проп | Тип | По умолчанию | Описание |
|
|
359
|
+
| --- | --- | --- | --- |
|
|
360
|
+
| `dateFrom` | `String` | `""` | Начало интервала |
|
|
361
|
+
| `dateTo` | `String` | `""` | Конец интервала |
|
|
362
|
+
| `label` | `String` | обязателен | Подпись над полями |
|
|
363
|
+
| `isRequired` | `Boolean` | `false` | Красная точка у подписи |
|
|
364
|
+
| `lang` | `String` | язык плагина | `"ru"` или `"en"`; действует и на подсказки полей, и на оба календаря |
|
|
365
|
+
|
|
366
|
+
События те же, что у `SelectDateIntervalFilter`: `update:dateFrom`,
|
|
367
|
+
`update:dateTo` и `changed`. Календари, ластики, подсказки и клавиатура —
|
|
368
|
+
тоже как у него (см. «SelectDateIntervalFilter»).
|
|
369
|
+
|
|
370
|
+
Подпись связана с полями для скринридера: оба поля — группа, названная
|
|
371
|
+
подписью, а каждое поле, как в фильтре, называется своей подсказкой «от» или
|
|
372
|
+
«до» с датой. Клик по подписи ничего не делает.
|
|
278
373
|
|
|
279
|
-
|
|
374
|
+
`isRequired` только показывает точку, как у `FormInput`. `class`, `style`,
|
|
375
|
+
все остальные атрибуты и слушатели ложатся на корень компонента (у `FormInput`
|
|
376
|
+
остальные атрибуты уходят на поле ввода).
|
|
377
|
+
|
|
378
|
+
### SelectSingleFilter
|
|
379
|
+
|
|
380
|
+
<select-single-filter
|
|
280
381
|
header="Вендор"
|
|
281
382
|
:items="[{ id: 'a', name: 'Первый' }]"
|
|
282
383
|
v-model="vendor"
|
|
@@ -284,7 +385,8 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
284
385
|
/>
|
|
285
386
|
|
|
286
387
|
`items` — массив объектов `{ id, name }`. `v-model` держит `id` выбранного или
|
|
287
|
-
`null`, если не выбрано.
|
|
388
|
+
`null`, если не выбрано. Не массив, в том числе `null` и `undefined`, — пустой
|
|
389
|
+
список; элементы-необъекты в массиве пропускаются.
|
|
288
390
|
|
|
289
391
|
| Проп | Тип | По умолчанию | Описание |
|
|
290
392
|
| --- | --- | --- | --- |
|
|
@@ -297,6 +399,11 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
297
399
|
События: `update:modelValue` и `changed` — при выборе элемента (повторный
|
|
298
400
|
клик по уже выбранному снимает выбор) и при очистке через ластик.
|
|
299
401
|
|
|
402
|
+
Высота 4.5rem и серая рамка встроены в фильтр: класс
|
|
403
|
+
`h-18 border border-gray-200` ему не нужен. `class` и остальные атрибуты
|
|
404
|
+
ложатся на корень фильтра. Без пунктов кнопки нет, а заголовок, высота и рамка
|
|
405
|
+
остаются.
|
|
406
|
+
|
|
300
407
|
С клавиатуры: пока список открыт, стрелки вверх и вниз переводят фокус по
|
|
301
408
|
пунктам и страницу не прокручивают. Отсчёт идёт от выбранного пункта: вниз —
|
|
302
409
|
следующий за ним, вверх — предыдущий; без выбранного вниз — первый пункт,
|
|
@@ -306,9 +413,9 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
306
413
|
возвращается на кнопку фильтра. У закрытого списка стрелки прокручивают
|
|
307
414
|
страницу.
|
|
308
415
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
416
|
+
Наведение подсвечивает пункт, но фокус не двигает: фокус меняют клавиатура и
|
|
417
|
+
клик. Пункт под мышью и пункт в фокусе с клавиатуры могут быть подсвечены
|
|
418
|
+
одновременно; стрелки продолжают от пункта в фокусе.
|
|
312
419
|
|
|
313
420
|
Список открывается в верхнем слое браузера (Popover API): его не обрезает
|
|
314
421
|
обёртка с прокруткой. Он открывается под полем, левым краем по левому
|
|
@@ -321,18 +428,50 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
321
428
|
внутри списка — нет. Открытие другого списка, календаря или меню
|
|
322
429
|
закрывает предыдущее.
|
|
323
430
|
|
|
324
|
-
###
|
|
431
|
+
### SelectSingleForm
|
|
325
432
|
|
|
326
|
-
|
|
433
|
+
Выбор одного пункта в форме, в виде `FormInput`: подпись над полем, рамка
|
|
434
|
+
поля на всю ширину формы, высотой 38px, как у `FormInput`. В рамке — кнопка
|
|
435
|
+
со списком и ластиком, та же, что у `SelectSingleFilter`.
|
|
436
|
+
|
|
437
|
+
<select-single-form
|
|
438
|
+
label="Вендор"
|
|
439
|
+
:items="vendors"
|
|
440
|
+
v-model="vendor"
|
|
441
|
+
:is-required="markVendorRequired"
|
|
442
|
+
/>
|
|
443
|
+
|
|
444
|
+
| Проп | Тип | По умолчанию | Описание |
|
|
445
|
+
| --- | --- | --- | --- |
|
|
446
|
+
| `items` | `Array` | обязателен | Массив `{ id, name }` |
|
|
447
|
+
| `modelValue` | `String \| Number` | `null` | `id` выбранного элемента или `null` |
|
|
448
|
+
| `label` | `String` | обязателен | Подпись над полем |
|
|
449
|
+
| `isRequired` | `Boolean` | `false` | Красная точка у подписи |
|
|
450
|
+
|
|
451
|
+
`items`, `v-model`, события, список и клавиатура — как у `SelectSingleFilter`
|
|
452
|
+
(см. «SelectSingleFilter»). Без пунктов кнопки нет, под подписью остаётся
|
|
453
|
+
пустая рамка.
|
|
454
|
+
|
|
455
|
+
Подпись связана с кнопкой для скринридера: кнопка называется подписью
|
|
456
|
+
и выбранным пунктом, у пустого поля — подписью. Клик по подписи ничего
|
|
457
|
+
не делает.
|
|
458
|
+
|
|
459
|
+
`isRequired` только показывает точку, как у `FormInput`. `class`, `style`,
|
|
460
|
+
все остальные атрибуты и слушатели ложатся на корень компонента (у `FormInput`
|
|
461
|
+
остальные атрибуты уходят на поле ввода).
|
|
462
|
+
|
|
463
|
+
### SelectMultipleFilter
|
|
464
|
+
|
|
465
|
+
<select-multiple-filter
|
|
327
466
|
header="Бренд"
|
|
328
467
|
:items="[{ id: 'rc', name: 'Royal Canin' }, { id: 'eukanuba', name: 'Eukanuba' }]"
|
|
329
468
|
v-model="brands"
|
|
330
469
|
@changed="reload"
|
|
331
470
|
/>
|
|
332
471
|
|
|
333
|
-
<select-multiple header="Мероприятие" :items="events" v-model="eventIds" with-search @changed="reload"/>
|
|
472
|
+
<select-multiple-filter header="Мероприятие" :items="events" v-model="eventIds" with-search @changed="reload"/>
|
|
334
473
|
|
|
335
|
-
Тот же фильтр, что `
|
|
474
|
+
Тот же фильтр, что `SelectSingleFilter`, но выбрать можно несколько пунктов.
|
|
336
475
|
`items` — массив объектов `{ id, name }`. `v-model` держит массив `id`
|
|
337
476
|
выбранных пунктов, пустой массив — ничего не выбрано. `id` — строка или число,
|
|
338
477
|
сравнение строгое.
|
|
@@ -354,8 +493,9 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
354
493
|
убирает. Массив из пропа компонент не меняет: он отдаёт новый, порядок `id` не
|
|
355
494
|
сортирует. `id`, которых нет среди пунктов, при переключении других пунктов
|
|
356
495
|
остаются в массиве, в надписи не считаются и ластик сами не показывают;
|
|
357
|
-
ластик отдаёт `[]` — уходят и они.
|
|
358
|
-
|
|
496
|
+
ластик отдаёт `[]` — уходят и они. Не массив в `items`, в том числе `null`
|
|
497
|
+
и `undefined`, — пустой список, элементы-необъекты в нём пропускаются; `null`
|
|
498
|
+
и `undefined` в `modelValue` — ничего не выбрано.
|
|
359
499
|
|
|
360
500
|
На кнопке: пока выбранных среди `items` нет — пусто; один — его название;
|
|
361
501
|
несколько — «Выбрано: 3». Считаются все пункты, а не только найденные поиском.
|
|
@@ -365,19 +505,20 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
365
505
|
на кнопку фильтра, а запрос поиска сбрасывается. `changed` уходит после
|
|
366
506
|
каждого выбора, и страница сразу перезапрашивает выдачу.
|
|
367
507
|
|
|
368
|
-
Список открывается так же, как у `
|
|
508
|
+
Список открывается так же, как у `SelectSingleFilter`: в верхнем слое браузера, место,
|
|
369
509
|
высота, прокрутка и способы закрытия те же, фокус после закрытия возвращается
|
|
370
510
|
на кнопку. Отличия: галочка стоит у каждого выбранного пункта; пункт
|
|
371
511
|
сообщает скринридеру, выбран ли он (`aria-pressed`).
|
|
372
|
-
Как и у `
|
|
373
|
-
пропали при открытом списке — список закрывается,
|
|
374
|
-
а вернувшиеся пункты появляются с закрытым списком.
|
|
512
|
+
Как и у `SelectSingleFilter`, без пунктов кнопки нет, а заголовок, высота
|
|
513
|
+
и рамка остаются. Пункты пропали при открытом списке — список закрывается,
|
|
514
|
+
запрос поиска сбрасывается, а вернувшиеся пункты появляются с закрытым списком.
|
|
375
515
|
|
|
376
|
-
С клавиатуры, пока список открыт, всё как у `
|
|
377
|
-
ведут фокус по пунктам по кругу, Enter или пробел переключают пункт и
|
|
378
|
-
список, Escape закрывает его без выбора. Если выбрано несколько
|
|
379
|
-
отсчёт идёт от первого выбранного среди видимых.
|
|
380
|
-
|
|
516
|
+
С клавиатуры, пока список открыт, всё как у `SelectSingleFilter`: стрелки вверх
|
|
517
|
+
и вниз ведут фокус по пунктам по кругу, Enter или пробел переключают пункт и
|
|
518
|
+
закрывают список, Escape закрывает его без выбора. Если выбрано несколько
|
|
519
|
+
пунктов, отсчёт идёт от первого выбранного среди видимых. Наведение подсвечивает
|
|
520
|
+
пункт, но фокус не двигает: фокус меняют клавиатура и клик, пункт под мышью и
|
|
521
|
+
пункт в фокусе могут быть подсвечены одновременно.
|
|
381
522
|
|
|
382
523
|
С `with-search` над пунктами стоит поле поиска: при прокрутке длинного списка
|
|
383
524
|
оно остаётся на месте. Имя пункта должно содержать запрос, регистр не важен,
|
|
@@ -385,21 +526,52 @@ Tailwind, `@tailwindcss/forms`, Inertia и какие-либо токены в C
|
|
|
385
526
|
строка «Ничего не найдено». Выбранные пункты, скрытые поиском, остаются
|
|
386
527
|
выбранными. Запрос не входит в `v-model`; он сбрасывается при каждом закрытии
|
|
387
528
|
списка, в том числе при выборе пункта. Ластик в поле очищает запрос. При
|
|
388
|
-
открытии списка фокус встаёт в поле; при загрузке страницы фокус в поле
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
529
|
+
открытии списка фокус встаёт в поле; при загрузке страницы фокус в поле не
|
|
530
|
+
уходит. Без Popover API список виден всегда, и фокус в поле сам не ставится.
|
|
531
|
+
Пробел в поле печатает пробел, Enter ничего не делает и форму не отправляет.
|
|
532
|
+
Поле — первая остановка стрелок: из него вниз — первый пункт, вверх — последний,
|
|
533
|
+
с краёв пунктов — обратно в поле. Без совпадений стрелки в поле ничего не
|
|
534
|
+
делают. Пока список открыт, Tab и Shift+Tab ходят по кругу внутри него: поле,
|
|
535
|
+
ластик поля, пока запрос не пуст, пункты; наружу, на страницу, фокус уходит
|
|
536
|
+
после закрытия списка. Ластик поля входит в Tab, но не в стрелки. Ластик на
|
|
537
|
+
кнопке фильтра идёт в Tab сразу после неё. Печатный символ и Backspace на
|
|
538
|
+
пункте, куда фокус перевели стрелки или Tab, уходят в поле, поэтому набор не
|
|
539
|
+
пропадает; мышь фокус на пункт не уводит. Пока список открыт, панель не
|
|
399
540
|
становится уже, чем при открытии, а поле не двигается, сколько бы пунктов ни
|
|
400
541
|
убрал поиск: открытая вниз панель становится ниже вместе с найденным, открытая
|
|
401
542
|
вверх не становится ниже, и пустое место остаётся под пунктами, у кнопки.
|
|
402
543
|
|
|
544
|
+
### SelectMultipleForm
|
|
545
|
+
|
|
546
|
+
Выбор нескольких пунктов в форме, в виде `FormInput`: подпись над полем, рамка
|
|
547
|
+
поля на всю ширину формы, высотой 38px, как у `FormInput`. В рамке — кнопка
|
|
548
|
+
со списком, поиском и ластиком, та же, что у `SelectMultipleFilter`.
|
|
549
|
+
|
|
550
|
+
<select-multiple-form label="Бренд" :items="brands" v-model="brandIds"/>
|
|
551
|
+
|
|
552
|
+
<select-multiple-form label="Мероприятие" :items="events" v-model="eventIds" with-search :is-required="markEventsRequired"/>
|
|
553
|
+
|
|
554
|
+
| Проп | Тип | По умолчанию | Описание |
|
|
555
|
+
| --- | --- | --- | --- |
|
|
556
|
+
| `items` | `Array` | обязателен | Массив `{ id, name }` |
|
|
557
|
+
| `modelValue` | `Array` | `[]` | `id` выбранных пунктов |
|
|
558
|
+
| `label` | `String` | обязателен | Подпись над полем |
|
|
559
|
+
| `isRequired` | `Boolean` | `false` | Красная точка у подписи |
|
|
560
|
+
| `withSearch` | `Boolean` | `false` | Поле поиска вверху списка |
|
|
561
|
+
| `lang` | `String` | язык плагина | `"ru"` или `"en"` — надпись, поле поиска, «Ничего не найдено», подписи обоих ластиков |
|
|
562
|
+
|
|
563
|
+
`items`, `v-model`, события, надпись на кнопке, список, поиск и клавиатура —
|
|
564
|
+
как у `SelectMultipleFilter` (см. «SelectMultipleFilter»). Без пунктов кнопки
|
|
565
|
+
нет, под подписью остаётся пустая рамка.
|
|
566
|
+
|
|
567
|
+
Подпись связана с кнопкой для скринридера: кнопка называется подписью
|
|
568
|
+
и надписью на кнопке, у пустого поля — подписью. Клик по подписи ничего
|
|
569
|
+
не делает.
|
|
570
|
+
|
|
571
|
+
`isRequired` только показывает точку, как у `FormInput`. `class`, `style`,
|
|
572
|
+
все остальные атрибуты и слушатели ложатся на корень компонента (у `FormInput`
|
|
573
|
+
остальные атрибуты уходят на поле ввода).
|
|
574
|
+
|
|
403
575
|
### InfoPill
|
|
404
576
|
|
|
405
577
|
Пилюля, которая только показывает текст: статус, счётчик, флаг, пометку.
|
|
@@ -621,13 +793,16 @@ exportOrders() {
|
|
|
621
793
|
таблицы и изменением размера окна. Открытие другого меню закрывает
|
|
622
794
|
предыдущее.
|
|
623
795
|
|
|
624
|
-
Пока меню открыто, стрелки вверх и вниз переводят фокус по пунктам и
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
796
|
+
Пока меню открыто, стрелки вверх и вниз переводят фокус по пунктам и страницу не
|
|
797
|
+
прокручивают: вниз — на первый пункт, вверх — на последний, дальше — по
|
|
798
|
+
соседним, с краёв — по кругу. Enter на пункте под фокусом выбирает его.
|
|
799
|
+
Наведение подсвечивает пункт, но фокус не двигает: фокус меняют клавиатура и
|
|
800
|
+
клик. Пункт под мышью и пункт в фокусе с клавиатуры могут быть подсвечены
|
|
801
|
+
одновременно; стрелки продолжают от пункта в фокусе.
|
|
802
|
+
|
|
803
|
+
После закрытия меню фокус возвращается на стрелку, если он был внутри меню и
|
|
804
|
+
после закрытия потерян. Фокус, который перешёл на другой элемент (например, в
|
|
805
|
+
модалку, открытую пунктом), сохраняется.
|
|
631
806
|
|
|
632
807
|
### HamburgerMenu
|
|
633
808
|
|
|
@@ -673,9 +848,15 @@ Escape, клик по пункту, прокрутка и изменение р
|
|
|
673
848
|
с `<hamburger-menu>` — `class`, `style`, `data-*` — ложатся на обёртку
|
|
674
849
|
кнопки.
|
|
675
850
|
|
|
676
|
-
Клавиатура и мышь — как в меню `DropdownButtonWithAction`: пока меню
|
|
677
|
-
|
|
678
|
-
|
|
851
|
+
Клавиатура и мышь — как в меню `DropdownButtonWithAction`: пока меню открыто,
|
|
852
|
+
стрелки вверх и вниз переводят фокус по пунктам, Enter выбирает пункт под
|
|
853
|
+
фокусом; наведение подсвечивает пункт, но фокус не двигает: фокус меняют
|
|
854
|
+
клавиатура и клик, а пункт под мышью и пункт в фокусе могут быть подсвечены
|
|
855
|
+
одновременно.
|
|
856
|
+
|
|
857
|
+
После закрытия меню фокус возвращается на кнопку меню, если он был внутри меню
|
|
858
|
+
и после закрытия потерян. Фокус, который перешёл на другой элемент (например, в
|
|
859
|
+
модалку, открытую пунктом), сохраняется.
|
|
679
860
|
|
|
680
861
|
### DataTable
|
|
681
862
|
|
|
@@ -1006,12 +1187,12 @@ rounded-lg`, `box-sizing: border-box`. Отступов у неё нет: фор
|
|
|
1006
1187
|
| `ConfirmationModal` — кнопка отмены | Отмена | Cancel |
|
|
1007
1188
|
| `DropdownButtonWithAction` — подпись стрелки для скринридера | Открыть меню | Open menu |
|
|
1008
1189
|
| `HamburgerMenu` — подпись кнопки для скринридера | Открыть меню | Open menu |
|
|
1009
|
-
| `
|
|
1010
|
-
| `
|
|
1011
|
-
| Ластик `Search`, `RussianMobileFilter`, `
|
|
1012
|
-
| `
|
|
1013
|
-
| `
|
|
1014
|
-
| `
|
|
1190
|
+
| `SelectDateFilter`, `SelectDateForm`, `SelectDateIntervalFilter`, `SelectDateIntervalForm` — месяцы, дни недели, кнопки календарей | по-русски | in English |
|
|
1191
|
+
| `SelectDateIntervalFilter`, `SelectDateIntervalForm` — подсказки полей | от / до | from / to |
|
|
1192
|
+
| Ластик `Search`, `RussianMobileFilter`, `SelectSingleFilter` и `SelectSingleForm` (язык плагина), `SelectMultipleFilter` и `SelectMultipleForm` (проп `lang`), `SelectDateFilter`, `SelectDateForm`, `SelectDateIntervalFilter` и `SelectDateIntervalForm` — подпись для скринридера | Очистить | Clear |
|
|
1193
|
+
| `SelectMultipleFilter`, `SelectMultipleForm` — надпись при нескольких выбранных | Выбрано: N | Selected: N |
|
|
1194
|
+
| `SelectMultipleFilter`, `SelectMultipleForm` — подсказка и имя поля поиска | Поиск | Search |
|
|
1195
|
+
| `SelectMultipleFilter`, `SelectMultipleForm` — нет совпадений | Ничего не найдено | Nothing found |
|
|
1015
1196
|
| `DataTable` — пагинация | Предыдущая / Следующая / Показаны результаты X - Y из Z | Previous / Next / Showing X - Y of Z results |
|
|
1016
1197
|
| `PageTabs` — имя навигации для скринридера | Закладки | Tabs |
|
|
1017
1198
|
| `PageCard` — доступное имя крестика | Назад | Back |
|
|
@@ -1019,8 +1200,9 @@ rounded-lg`, `box-sizing: border-box`. Отступов у неё нет: фор
|
|
|
1019
1200
|
| `TextPopover` — подпись кнопки и имя области | Показать текст / Полный текст | Show text / Full text |
|
|
1020
1201
|
|
|
1021
1202
|
Формат даты — `дд.мм.гггг` в обоих языках: это формат значения, а не текст.
|
|
1022
|
-
Неделя начинается с понедельника. Календари `
|
|
1023
|
-
при монтировании: смена языка после
|
|
1203
|
+
Неделя начинается с понедельника. Календари `SelectDateFilter`, `SelectDateForm`,
|
|
1204
|
+
`SelectDateIntervalFilter` и `SelectDateIntervalForm` берут язык при монтировании: смена языка после
|
|
1205
|
+
монтирования в них не отражается.
|
|
1024
1206
|
|
|
1025
1207
|
## Клавиатурная навигация
|
|
1026
1208
|
|
|
@@ -1038,7 +1220,7 @@ Vimium, Vimari, Vimlike — по их подсказкам, как мышью;
|
|
|
1038
1220
|
выбирают только момент. Поля, крестик `NotificationMessage`, кнопки
|
|
1039
1221
|
`ConfirmationModal` и `DropdownButtonWithAction` показывают фокус при любом
|
|
1040
1222
|
его появлении, в том числе после клика мышью; остальные кнопки и ссылки —
|
|
1041
|
-
только с клавиатуры. Стрелки месяцев и подпись месяца в календаре
|
|
1223
|
+
только с клавиатуры. Стрелки месяцев и подпись месяца в календаре поля даты
|
|
1042
1224
|
берут тот же вид, когда фокус в них с клавиатуры.
|
|
1043
1225
|
|
|
1044
1226
|
Vimlike (Safari на iPhone, iPad и Mac) считает кнопкой любой элемент
|
|
@@ -1048,17 +1230,19 @@ Vimlike (Safari на iPhone, iPad и Mac) считает кнопкой любо
|
|
|
1048
1230
|
бы тексту, иконке, у которой нет `click()`, и скрытой подписи, которую Vimlike
|
|
1049
1231
|
считает невидимой. Поэтому содержимое кнопок и ссылок пакета — текст, иконки,
|
|
1050
1232
|
скрытые подписи — с курсором `default` и не ловит указатель: мышь над ним
|
|
1051
|
-
видит руку самой кнопки. По той же причине поле даты `
|
|
1052
|
-
лежит не внутри кнопки календаря, а под ней: поле
|
|
1053
|
-
считал бы кнопкой вместо неё. В поле по-прежнему можно
|
|
1054
|
-
дату.
|
|
1055
|
-
|
|
1056
|
-
Подсказки Vimlike в открытых меню, списках `
|
|
1057
|
-
`
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1233
|
+
видит руку самой кнопки. По той же причине поле даты `SelectDateFilter`, `SelectDateForm`,
|
|
1234
|
+
`SelectDateIntervalFilter` и `SelectDateIntervalForm` лежит не внутри кнопки календаря, а под ней: поле
|
|
1235
|
+
внутри кнопки Vimlike считал бы кнопкой вместо неё. В поле по-прежнему можно
|
|
1236
|
+
перейти Tab и набрать дату.
|
|
1237
|
+
|
|
1238
|
+
Подсказки Vimlike в открытых меню, списках `SelectSingleFilter`,
|
|
1239
|
+
`SelectSingleForm`, `SelectMultipleFilter` и `SelectMultipleForm` и календарях
|
|
1240
|
+
`SelectDateFilter`, `SelectDateForm`, `SelectDateIntervalFilter`
|
|
1241
|
+
и `SelectDateIntervalForm` не видны: Vimlike рисует
|
|
1242
|
+
их под верхним слоем браузера, в котором открываются эти панели. Vimium
|
|
1243
|
+
выводит свои подсказки в верхний слой, и у него такой проблемы нет. В Vimlike
|
|
1244
|
+
панель открывают подсказкой её кнопки, а дальше выбирают стрелками и Enter:
|
|
1245
|
+
пункт списка или меню, день календаря.
|
|
1062
1246
|
|
|
1063
1247
|
## SSR
|
|
1064
1248
|
|
|
@@ -1069,8 +1253,10 @@ Inertia SSR), а серверная разметка гидратируется
|
|
|
1069
1253
|
- `PageCard` на сервере рисует крестик, только если задан `fallback-url`:
|
|
1070
1254
|
адрес возврата известен только в браузере, и крестик, ведущий на него,
|
|
1071
1255
|
появляется после монтирования;
|
|
1072
|
-
- `
|
|
1073
|
-
|
|
1256
|
+
- `SelectDateFilter`, `SelectDateForm`, `SelectDateIntervalFilter`
|
|
1257
|
+
и `SelectDateIntervalForm` загружают Pikaday в браузере при монтировании:
|
|
1258
|
+
календари появляются, когда загрузка
|
|
1259
|
+
закончится;
|
|
1074
1260
|
- остальные компоненты рендерятся на сервере так же, как в браузере.
|
|
1075
1261
|
|
|
1076
1262
|
## Правила API пакета
|
|
@@ -1081,12 +1267,13 @@ Inertia SSR), а серверная разметка гидратируется
|
|
|
1081
1267
|
- Значение компонента передаётся через `v-model` (проп `modelValue` и
|
|
1082
1268
|
событие `update:modelValue`) и не обязательно: компонент обязан
|
|
1083
1269
|
отрисовываться без переданного значения. `required: true` оставляют
|
|
1084
|
-
только там, без чего компонент бессмыслен, — например, у `items`
|
|
1085
|
-
`
|
|
1270
|
+
только там, без чего компонент бессмыслен, — например, у `items`
|
|
1271
|
+
в `SelectSingleFilter` и `SelectSingleForm`, у `header` во всех фильтрах
|
|
1272
|
+
или у `label` полей формы.
|
|
1086
1273
|
- Именованные модели (`v-model:date-from`, `v-model:date-to`, как у
|
|
1087
|
-
`
|
|
1088
|
-
значениями. У компонента с одним значением
|
|
1089
|
-
для него это и есть обычный `v-model`.
|
|
1274
|
+
`SelectDateIntervalFilter` и `SelectDateIntervalForm`) — исключение для
|
|
1275
|
+
компонентов с несколькими значениями. У компонента с одним значением
|
|
1276
|
+
именованная модель не нужна: для него это и есть обычный `v-model`.
|
|
1090
1277
|
- Булев проп называется `is*`, если описывает состояние компонента
|
|
1091
1278
|
(`isRequired`, `isLoading`), и `with*`, если описывает необязательную
|
|
1092
1279
|
возможность (`withPulse` у `Dot`).
|
|
@@ -1142,10 +1329,10 @@ Inertia SSR), а серверная разметка гидратируется
|
|
|
1142
1329
|
|
|
1143
1330
|
Правило пакета — значение через `v-model` — относится к состоянию, которое
|
|
1144
1331
|
компонент меняет сам: меню `DropdownButtonWithAction` закрывается по клику
|
|
1145
|
-
вне, `
|
|
1146
|
-
никогда. Обе кнопки и Escape только сообщают родителю решение
|
|
1147
|
-
а закрыть модалку, оставить её открытой на время запроса или
|
|
1148
|
-
следующую — решает родитель.
|
|
1332
|
+
вне, `SelectSingleFilter` меняет выбор. `ConfirmationModal` свою видимость
|
|
1333
|
+
не меняет никогда. Обе кнопки и Escape только сообщают родителю решение
|
|
1334
|
+
пользователя, а закрыть модалку, оставить её открытой на время запроса или
|
|
1335
|
+
открыть следующую — решает родитель.
|
|
1149
1336
|
|
|
1150
1337
|
`v-model` обещал бы двустороннюю связь, которой нет, поэтому видимость
|
|
1151
1338
|
передаётся пропом `isOpen`.
|
|
@@ -1164,12 +1351,24 @@ Inertia SSR), а серверная разметка гидратируется
|
|
|
1164
1351
|
|
|
1165
1352
|
npm run playground
|
|
1166
1353
|
|
|
1167
|
-
Поднимает демо-страницы со всеми
|
|
1354
|
+
Поднимает демо-страницы со всеми двадцатью четырьмя компонентами в двух окружениях:
|
|
1168
1355
|
голом (без Tailwind и стилей приложения) и в окружении приложения (с
|
|
1169
1356
|
Tailwind, `@tailwindcss/forms` и типографикой, как у потребителя). Это
|
|
1170
1357
|
основной способ посмотреть, как компоненты выглядят и ведут себя, а не
|
|
1171
1358
|
угадывать по исходникам или по этому README.
|
|
1172
1359
|
|
|
1360
|
+
### Браузерные тесты
|
|
1361
|
+
|
|
1362
|
+
npm run test:browser
|
|
1363
|
+
|
|
1364
|
+
Собирает пакет и прогоняет Playground в Chromium и WebKit — движке Safari.
|
|
1365
|
+
Установленный Safari тесты не запускают. Запускать на macOS: WebKit на Linux
|
|
1366
|
+
фокусирует кнопки по клику иначе, чем Safari. Перед первым запуском:
|
|
1367
|
+
|
|
1368
|
+
npx playwright install chromium webkit
|
|
1369
|
+
|
|
1370
|
+
Тесты только локальные, в GitHub Actions они не входят.
|
|
1371
|
+
|
|
1173
1372
|
## Что пакет берёт у приложения
|
|
1174
1373
|
|
|
1175
1374
|
Базовую типографику — семейство шрифта, размер, `line-height`. Он наследует её
|
|
@@ -1180,6 +1379,43 @@ Tailwind, `@tailwindcss/forms` и типографикой, как у потре
|
|
|
1180
1379
|
Правила номера телефона в `RussianMobileFilter` — российские; язык текстов
|
|
1181
1380
|
задаётся, см. «Языки».
|
|
1182
1381
|
|
|
1382
|
+
## Обновление с 0.19
|
|
1383
|
+
|
|
1384
|
+
| Было | Стало |
|
|
1385
|
+
| --- | --- |
|
|
1386
|
+
| `<select-single class="h-18 border border-gray-200" header="…">` | `<select-single-filter header="…">` — высота и рамка встроены |
|
|
1387
|
+
| `<select-multiple class="h-18 border border-gray-200" header="…">` | `<select-multiple-filter header="…">` |
|
|
1388
|
+
| `<select-date-interval class="h-18 border border-gray-200" header="…">` | `<select-date-interval-filter header="…">` |
|
|
1389
|
+
| `"select-source": SelectSingle` (проект регистрирует компонент под своим именем тега) | `"select-source": SelectSingleFilter`; так же для `SelectMultiple` и `SelectDateInterval` |
|
|
1390
|
+
| `SelectSingle` в форме рядом с `FormInput` | `<select-single-form label="…">` |
|
|
1391
|
+
| `SelectMultiple` в форме | `<select-multiple-form label="…">` |
|
|
1392
|
+
| `SelectDateInterval` в форме | `<select-date-interval-form label="…">` |
|
|
1393
|
+
|
|
1394
|
+
`import { SelectSingle }` больше не работает: имена `SelectSingle`,
|
|
1395
|
+
`SelectMultiple` и `SelectDateInterval` из пакета убраны. Остальные классы
|
|
1396
|
+
на фильтрах (`ml-2` и т. п.) переносятся как есть.
|
|
1397
|
+
|
|
1398
|
+
В формах меняются и пропы: `header` становится `label`, `class="border
|
|
1399
|
+
border-gray-200"` убирается (на корне формы он обвёл бы подпись вместе с полем),
|
|
1400
|
+
а `isLoading` у форм нет.
|
|
1401
|
+
|
|
1402
|
+
Наведение мыши в списках и меню больше не двигает фокус: оно только подсвечивает
|
|
1403
|
+
пункт, фокус меняют клавиатура и клик.
|
|
1404
|
+
|
|
1405
|
+
Цветные пункты меню `DropdownButtonWithAction` и `HamburgerMenu` теперь всегда
|
|
1406
|
+
с фоном своего цвета: например, красный пункт «Удалить» / «Delete» в меню
|
|
1407
|
+
строки получает светло-красный фон.
|
|
1408
|
+
|
|
1409
|
+
В Safari фокус после закрытия меню `DropdownButtonWithAction` и `HamburgerMenu`
|
|
1410
|
+
— Escape, если фокус был в меню, выбор пункта мышью или клавиатурой, закрытие
|
|
1411
|
+
модалки, открытой пунктом, — возвращается на кнопку меню, как в Chrome.
|
|
1412
|
+
|
|
1413
|
+
`SelectDateFilter` и `SelectDateForm` — новые компоненты одной даты, у них
|
|
1414
|
+
нет предшественника: в таблице их нет.
|
|
1415
|
+
|
|
1416
|
+
`0.20.0` не подтянется по `^0.19.x`: для версий `0.x` знак `^` пропускает
|
|
1417
|
+
только патчи. Обновление — `npm install @boobooking/dashboard-ui-components@^0.20.0`.
|
|
1418
|
+
|
|
1183
1419
|
## Обновление с 0.15
|
|
1184
1420
|
|
|
1185
1421
|
| Было | Стало |
|