plugin-ui-for-kzt 0.0.23 → 0.0.25

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.
Files changed (75) hide show
  1. package/dist/assets/0e28e37419c99ac65b12.png +0 -0
  2. package/dist/assets/264165b2b0e8a6840eb0.png +0 -0
  3. package/dist/components/{DataTable/DataTable.vue.d.ts → BaseDefaultPages/BaseDefaultPages.vue.d.ts} +8 -6
  4. package/dist/components/BaseInput/BaseInput.vue.d.ts +1 -1
  5. package/dist/components/{Tooltip/Tooltip.vue.d.ts → BasePageLoader/BasePageLoader.vue.d.ts} +24 -11
  6. package/dist/components/BaseTable/BaseTable.vue.d.ts +44 -0
  7. package/dist/components/BaseToast/BaseToast.vue.d.ts +69 -0
  8. package/dist/composables/useToast.d.ts +2 -0
  9. package/dist/index.d.ts +6 -5
  10. package/dist/index.js +1 -1
  11. package/dist/plugins/toastPlugin.d.ts +4 -0
  12. package/dist/sprite.svg +1 -1
  13. package/dist/store/toast.d.ts +8 -0
  14. package/example/App.vue +196 -29
  15. package/package.json +1 -1
  16. package/src/assets/404.png +0 -0
  17. package/src/assets/icons/arrow-down-stick.svg +4 -0
  18. package/src/assets/icons/edit-table.svg +5 -0
  19. package/src/assets/icons/ellipsis.svg +5 -0
  20. package/src/assets/icons/loading-page-default.svg +4 -0
  21. package/src/assets/icons/loading-page-error.svg +6 -0
  22. package/src/assets/icons/loading-page-success.svg +5 -0
  23. package/src/assets/icons/loading-page-warning.svg +6 -0
  24. package/src/assets/icons/more-dots.svg +5 -0
  25. package/src/assets/icons/time-table.svg +7 -0
  26. package/src/assets/icons/toast-error.svg +3 -0
  27. package/src/assets/icons/toast-info.svg +3 -0
  28. package/src/assets/icons/toast-success.svg +3 -0
  29. package/src/assets/icons/toast-warning.svg +3 -0
  30. package/src/assets/icons/trash-table.svg +7 -0
  31. package/src/assets/tech-work.png +0 -0
  32. package/src/components/BaseChips/BaseChips.vue +3 -1
  33. package/src/components/BaseDefaultPages/BaseDefaultPages.vue +140 -0
  34. package/src/components/BaseDefaultPages/README.md +128 -0
  35. package/src/components/BaseOpenedListItem/BaseOpenedListItem.vue +3 -3
  36. package/src/components/BasePageLoader/BasePageLoader.vue +211 -0
  37. package/src/components/BasePageLoader/README.md +80 -0
  38. package/src/components/BaseSelect/BaseSelect.vue +7 -3
  39. package/src/components/BaseTable/BaseTable.vue +411 -0
  40. package/src/components/BaseTable/README.md +294 -0
  41. package/src/components/BaseToast/BaseToast.vue +200 -0
  42. package/src/components/BaseToast/README.md +103 -0
  43. package/src/components/BaseTooltip/BaseTooltip.vue +1 -0
  44. package/src/components/BaseUpload/BaseUpload.vue +1 -1
  45. package/src/composables/useToast.ts +10 -0
  46. package/src/index.ts +17 -13
  47. package/src/plugins/toastPlugin.ts +100 -0
  48. package/src/store/toast.ts +59 -0
  49. package/src/styles/root.scss +2 -0
  50. package/src/styles/toast.scss +36 -0
  51. package/src/types/default-pages.d.ts +6 -0
  52. package/src/types/loading-page.d.ts +12 -0
  53. package/src/types/pagination.d.ts +1 -0
  54. package/src/types/table.d.ts +33 -0
  55. package/src/types/toast.d.ts +25 -0
  56. package/webpack.config.js +12 -0
  57. package/dist/components/Spinner/Spinner.vue.d.ts +0 -20
  58. package/dist/components/Toaster/Toaster.vue.d.ts +0 -80
  59. package/dist/components/Toaster/timer.d.ts +0 -12
  60. package/dist/plugins/toasterPlugin.d.ts +0 -26
  61. package/src/components/DataTable/DataTable.vue +0 -169
  62. package/src/components/DataTable/README.md +0 -57
  63. package/src/components/Spinner/README.md +0 -35
  64. package/src/components/Spinner/Spinner.vue +0 -60
  65. package/src/components/Toaster/README.md +0 -70
  66. package/src/components/Toaster/Toaster.vue +0 -235
  67. package/src/components/Toaster/timer.ts +0 -45
  68. package/src/components/Tooltip/README.md +0 -37
  69. package/src/components/Tooltip/Tooltip.vue +0 -96
  70. package/src/components/icons/CloseIcon.vue +0 -5
  71. package/src/components/icons/ErrorIcon.vue +0 -7
  72. package/src/components/icons/InfoIcon.vue +0 -7
  73. package/src/components/icons/SuccessIcon.vue +0 -6
  74. package/src/components/icons/WarningIcon.vue +0 -7
  75. package/src/plugins/toasterPlugin.ts +0 -179
@@ -222,6 +222,10 @@ defineSlots<{
222
222
  border-radius: var(--corner-radius-m);
223
223
  }
224
224
 
225
+ &__header_value {
226
+ color: var(--primary-text-primary);
227
+ }
228
+
225
229
  &__placeholder {
226
230
  @include text-clamp(1);
227
231
 
@@ -257,7 +261,7 @@ defineSlots<{
257
261
 
258
262
  &.--small-size {
259
263
  #{$select} {
260
- &__header_value {
264
+ &__header_value, &__placeholder {
261
265
  font: var(--typography-text-m-regular);
262
266
  }
263
267
 
@@ -280,7 +284,7 @@ defineSlots<{
280
284
 
281
285
  &.--medium-size {
282
286
  #{$select} {
283
- &__header_value {
287
+ &__header_value, &__placeholder {
284
288
  font: var(--typography-text-m-regular);
285
289
  }
286
290
 
@@ -298,7 +302,7 @@ defineSlots<{
298
302
 
299
303
  &.--large-size {
300
304
  #{$select} {
301
- &__header_value {
305
+ &__header_value, &__placeholder {
302
306
  font: var(--typography-text-l-regular);
303
307
  }
304
308
 
@@ -0,0 +1,411 @@
1
+ <template>
2
+ <div class="base-table">
3
+ <div class="base-table__wrapper">
4
+ <table class="base-table__table">
5
+ <thead v-if="hasHeader">
6
+ <slot name="header">
7
+ <tr class="base-table__header">
8
+ <!-- Чек‑бокс «Выбрать всё» -->
9
+ <th v-if="showRowSelection" class="base-table__header-column">
10
+ <span v-if="checkboxTitle">{{ checkboxTitle }}</span>
11
+ <BaseCheckbox id="selectAll" size="small" v-model="isAllSelected" />
12
+ </th>
13
+
14
+ <!-- Обычные колонки -->
15
+ <th v-for="col in columns"
16
+ :key="String(col.key)"
17
+ class="base-table__header-column"
18
+ @click="onHeaderClick(col)"
19
+ :title="col.tooltip"
20
+ >
21
+ <div class="column-header">
22
+ <component
23
+ v-if="col.icons?.[0]"
24
+ :is="col.icons[0]"
25
+ class="header-icon"
26
+ />
27
+ <span v-if="col.label">{{ col.label }}</span>
28
+ <component
29
+ v-if="col.icons?.[1]"
30
+ :is="col.icons[1]"
31
+ class="header-icon"
32
+ />
33
+ <BaseIcon
34
+ v-if="col.sortable"
35
+ name="arrow-up"
36
+ size="extra-small"
37
+ class="base-table__sort-icon"
38
+ :class="{ '--active': sortOrder === 'desc' && sortKey === col.key }"
39
+ />
40
+ </div>
41
+ </th>
42
+
43
+ <!-- Колонка‑действий -->
44
+ <th v-if="showActions" class="base-table__cell base-table__header-column base-table__actions-column"></th>
45
+ </tr>
46
+ </slot>
47
+ </thead>
48
+ <transition-group tag="tbody"
49
+ name="row"
50
+ class="base-table__tbody"
51
+ appear
52
+ >
53
+ <!-- Список строк -->
54
+ <template v-if="paginatedData.length">
55
+ <tr
56
+ v-for="(row, rowIndex) in paginatedData"
57
+ :key="rowId(row)"
58
+ :class="{ '--is-disabled': row.disabled }"
59
+ class="base-table__row"
60
+ >
61
+
62
+ <!-- Чек‑бокс отдельной строки -->
63
+ <td v-if="showRowSelection" class="base-table__cell">
64
+ <BaseCheckbox
65
+ :id="row.id"
66
+ size="small"
67
+ :modelValue="isRowSelected(row)"
68
+ :disabled="row.disabled"
69
+ @update:modelValue="toggleRow(row)"
70
+ />
71
+ </td>
72
+
73
+ <!-- Ячейки -->
74
+ <td v-for="col in columns"
75
+ :key="String(col.key)"
76
+ class="base-table__cell">
77
+ <!-- Пользовательский рендеринг ячейки -->
78
+ <slot
79
+ :name="`cell-${String(col.key)}`"
80
+ :row="row"
81
+ :value="row[col.key]"
82
+ >
83
+ {{ row[col.key] }}
84
+ </slot>
85
+ </td>
86
+
87
+ <!-- Колонка‑действий -->
88
+ <td v-if="showActions" class="base-table__cell base-table__actions-column">
89
+ <slot name="actions" :row="row">
90
+ <BaseButton
91
+ v-for="action in actions"
92
+ :key="action.key"
93
+ :disabled="row.disabled"
94
+ size="extra-small"
95
+ color="quaternary-gray"
96
+ @click="action.handler(row)"
97
+ >
98
+ <BaseIcon :name="action.icon" size="extra-small" />
99
+ </BaseButton>
100
+ </slot>
101
+ </td>
102
+
103
+ <td v-if="$slots['row-menu']" class="base-table__cell base-table__menu-column">
104
+ <slot name="row-menu" :row="row"></slot>
105
+ </td>
106
+ </tr>
107
+ </template>
108
+
109
+ <!-- Пустой набор данных -->
110
+ <tr v-else>
111
+ <td :colspan="colspan" class="base-table__empty">
112
+ <slot name="empty">
113
+ <div>
114
+ Нет данных
115
+ </div>
116
+ </slot>
117
+ </td>
118
+ </tr>
119
+ </transition-group>
120
+
121
+ </table>
122
+
123
+ <div v-if="showPagination" class="base-table__footer">
124
+ <BasePagination
125
+ :totalPages="totalPages"
126
+ :currentPage="currentPage"
127
+ size="small"
128
+ v-bind="pagination"
129
+ @update:currentPage="onPageChange"
130
+ />
131
+ </div>
132
+ </div>
133
+ </div>
134
+ </template>
135
+
136
+ <script setup lang="ts">
137
+ import { ref, computed, watch, defineProps, defineEmits, useSlots } from 'vue'
138
+ import BasePagination from '../BasePagination/BasePagination.vue'
139
+ import BaseCheckbox from '../BaseCheckbox/BaseCheckbox.vue'
140
+ import BaseButton from '../BaseButton/BaseButton.vue'
141
+ import BaseIcon from '../BaseIcon/BaseIcon.vue'
142
+ import type {
143
+ Row,
144
+ Column,
145
+ BaseTableProps,
146
+ } from '../../types/table'
147
+ import type { TPaginationProps } from '../../types/pagination'
148
+
149
+ const props = defineProps<BaseTableProps>()
150
+ const emit = defineEmits<{
151
+ (e: 'update:selected', rows: Row[]): void
152
+ (e: 'select-all', selected: boolean): void
153
+ (e: 'sort-change', payload: { key: string; order: 'asc' | 'desc' }): void
154
+ (e: 'page-change', page: number): void
155
+ }>()
156
+
157
+ const colspan = computed(() => {
158
+ const base = props.columns.length
159
+ const extra =
160
+ (props.showRowSelection ? 1 : 0) +
161
+ (props.showActions ? 1 : 0) +
162
+ (useSlots()['row-menu'] ? 1 : 0)
163
+ return base + extra
164
+ })
165
+
166
+ const hasHeader = computed(() => props.columns.length > 0 || !!useSlots().header)
167
+
168
+ /* ---------- Утилиты ---------- */
169
+ function rowId(row: Row): unknown {
170
+ if (props.rowKey) {
171
+ return typeof props.rowKey === 'function'
172
+ ? (props.rowKey as (r: Row) => unknown)(row)
173
+ : (row as any)[props.rowKey]
174
+ }
175
+
176
+ return (row as any).__uid ?? JSON.stringify(row)
177
+ }
178
+
179
+ /* ---------- СОРТИРОВКА ---------- */
180
+ const sortKey = ref<string | null>(null)
181
+ const sortOrder = ref<'asc' | 'desc'>('asc')
182
+
183
+ function onHeaderClick(col: Column) {
184
+ if (!col.sortable) return
185
+
186
+ if (sortKey.value === col.key) {
187
+ sortOrder.value = sortOrder.value === 'desc' ? 'asc' : 'desc'
188
+ } else {
189
+ sortKey.value = col.key
190
+ sortOrder.value = 'desc'
191
+ }
192
+
193
+ emit('sort-change', { key: col.key, order: sortOrder.value })
194
+ }
195
+
196
+ /* ---------- ПАГИНАЦИЯ ---------- */
197
+ const pagination = computed<TPaginationProps>(() => props.pagination ?? { perPage: 10 })
198
+ const perPage = computed(() => pagination.value.totalPages ?? 10)
199
+
200
+ const totalPages = computed(() => {
201
+ if (!props.pagination) return 1
202
+ return Math.max(1, Math.ceil(props.data.length / perPage.value))
203
+ })
204
+
205
+ const showPagination = computed(() => totalPages.value > 1)
206
+
207
+ const currentPage = ref(pagination.value.currentPage ?? 1)
208
+
209
+ function onPageChange(page: number) {
210
+ currentPage.value = page
211
+ emit('page-change', page)
212
+ }
213
+
214
+ const paginatedData = computed(() => {
215
+ const start = (currentPage.value - 1) * perPage.value
216
+ const end = start + perPage.value
217
+ return props.data.slice(start, end)
218
+ })
219
+
220
+ /* ---------- ВЫБОР СТРОК (чек‑боксы) ---------- */
221
+ const selectedIds = ref<Set<unknown>>(new Set())
222
+
223
+ function isRowSelected(row: Row): boolean {
224
+ return selectedIds.value.has(rowId(row))
225
+ }
226
+
227
+ function toggleRow(row: Row) {
228
+ const id = rowId(row)
229
+ if (selectedIds.value.has(id)) selectedIds.value.delete(id)
230
+ else selectedIds.value.add(id)
231
+ emitSelected()
232
+ }
233
+
234
+ /* computed‑getter/setter «Выбрать всё» */
235
+ const isAllSelected = computed<boolean>({
236
+ get: () => {
237
+ if (!props.showRowSelection) return false
238
+ return props.data.length > 0 && props.data.every((r: Row) => selectedIds.value.has(rowId(r)))
239
+ },
240
+ set: (val: boolean) => {
241
+ if (!props.showRowSelection) return
242
+ if (val) props.data.forEach((r: Row) => selectedIds.value.add(rowId(r)))
243
+ else selectedIds.value.clear()
244
+ emitSelected()
245
+ },
246
+ })
247
+
248
+ /** Эмитим массив выбранных строк */
249
+ function emitSelected() {
250
+ const rows = props.data.filter((r: Row) => selectedIds.value.has(rowId(r)))
251
+ emit('update:selected', rows)
252
+ }
253
+
254
+ /* Синхронзация при изменении props.data */
255
+ watch(
256
+ () => props.data,
257
+ () => {
258
+ const newIds = new Set(props.data.map(rowId))
259
+ selectedIds.value.forEach(id => {
260
+ if (!newIds.has(id)) selectedIds.value.delete(id)
261
+ })
262
+ },
263
+ { deep: true }
264
+ )
265
+
266
+ /* ---------- Подтаблица (expand / collapse) ---------- */
267
+ const expandedRows = ref<Set<number>>(new Set())
268
+ function toggleSubRow(idx: number) {
269
+ if (expandedRows.value.has(idx)) expandedRows.value.delete(idx)
270
+ else expandedRows.value.add(idx)
271
+ }
272
+ </script>
273
+
274
+ <style scoped lang="scss">
275
+ @import '@/styles/variables';
276
+ @import '@/styles/root';
277
+
278
+ .base-table {
279
+ width: 100%;
280
+
281
+ &__wrapper {
282
+ display: flex;
283
+ flex-direction: column;
284
+ border: 1px solid var(--primary-black-200);
285
+ border-radius: var(--corner-radius-m);
286
+ background: var(--bg-light);
287
+ overflow: hidden;
288
+ }
289
+
290
+ &__table {
291
+ width: 100%;
292
+ border-collapse: collapse;
293
+ table-layout: fixed;
294
+ }
295
+
296
+ &__header-column,
297
+ &__cell {
298
+ text-align: left;
299
+ vertical-align: middle;
300
+ }
301
+
302
+ &__header {
303
+ width: 100%;
304
+ background: var(--primary-black-50);
305
+ border: 1px solid var(--primary-black-200);
306
+ color: var(--primary-black-600);
307
+ font: var(--typography-text-s-medium);
308
+ }
309
+
310
+ &__cell {
311
+ padding: var(--spacing-l) var(--spacing-xl);
312
+ }
313
+
314
+ &__cell:nth-child(odd) {
315
+ color: var(--primary-black-600);
316
+ }
317
+
318
+ &__cell:nth-child(even) {
319
+ color: var(--primary-text-primary);
320
+ }
321
+
322
+ &__header-column {
323
+ padding: var(--spacing-m) var(--spacing-xl);
324
+ user-select: none;
325
+ }
326
+
327
+ &__empty {
328
+ text-align: center;
329
+ font: var(--typography-text-xl-medium);
330
+ padding: var(--spacing-m);
331
+ width: 100%;
332
+ }
333
+
334
+ .column-header {
335
+ display: flex;
336
+ align-items: center;
337
+ gap: 4px;
338
+ cursor: pointer;
339
+ }
340
+
341
+ &__sort-icon {
342
+ color: var(--primary-black-600);
343
+ transition: transform 0.2s;
344
+ }
345
+
346
+ &__sort-icon.--active {
347
+ transform: rotate(180deg);
348
+ }
349
+
350
+ &__actions-column,
351
+ &__menu-column {
352
+ width: auto;
353
+ text-align: right;
354
+ }
355
+
356
+ &__footer {
357
+ padding: 20px;
358
+ display: flex;
359
+ justify-content: center;
360
+ background: var(--bg-light);
361
+ }
362
+
363
+ &__row {
364
+ border-bottom: 1px solid var(--primary-black-100);
365
+
366
+ &:hover {
367
+ background: var(--primary-black-100);
368
+ }
369
+
370
+ &.--is-disabled {
371
+ cursor: not-allowed;
372
+ background: var(--primary-black-50);
373
+ }
374
+ }
375
+ }
376
+
377
+ .row-enter-active,
378
+ .row-leave-active {
379
+ transition: opacity 0.3s ease, transform 0.3s ease;
380
+ }
381
+
382
+ .row-enter-from {
383
+ opacity: 0;
384
+ transform: translateY(12px);
385
+ }
386
+ .row-enter-to {
387
+ opacity: 1;
388
+ transform: translateY(0);
389
+ }
390
+
391
+ .row-leave-from {
392
+ opacity: 1;
393
+ transform: translateY(0);
394
+ }
395
+ .row-leave-to {
396
+ opacity: 0;
397
+ transform: translateY(-12px);
398
+ }
399
+
400
+ .row-leave-active {
401
+ position: absolute;
402
+ width: 100%;
403
+ left: 0;
404
+ top: -250px;
405
+ opacity: 0;
406
+ }
407
+
408
+ .base-table__tbody {
409
+ position: relative;
410
+ }
411
+ </style>