plugin-ui-for-kzt 0.0.16 → 0.0.18
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/dist/components/BaseBadge/BaseBadge.vue.d.ts +49 -0
- package/dist/components/BaseBadge/BaseBadgeGroup.vue.d.ts +30 -0
- package/dist/components/BaseButton/BaseButton.vue.d.ts +3 -3
- package/dist/components/BaseCheckbox/BaseCheckbox.vue.d.ts +4 -4
- package/dist/components/BaseChips/BaseChips.vue.d.ts +27 -0
- package/dist/components/BaseDropdown/BaseDropdown.vue.d.ts +3 -3
- package/dist/components/BaseInput/BaseInput.vue.d.ts +5 -5
- package/dist/components/BaseInputCalendar/BaseInputCalendar.vue.d.ts +5 -5
- package/dist/components/BaseInputCurrency/BaseInputCurrency.vue.d.ts +5 -5
- package/dist/components/BaseInputEmail/BaseInputEmail.vue.d.ts +5 -5
- package/dist/components/BaseInputPhone/BaseInputPhone.vue.d.ts +5 -5
- package/dist/components/BaseModal/BaseModal.vue.d.ts +4 -0
- package/dist/components/BaseOpenedListItem/BaseOpenedListItem.vue.d.ts +3 -3
- package/dist/components/BasePagination/BasePagination.vue.d.ts +1 -1
- package/dist/components/BaseRadio/BaseRadio.vue.d.ts +4 -4
- package/dist/components/BaseSegmentedButtons/BaseSegmentedButtons.vue.d.ts +3 -3
- package/dist/components/BaseSelect/BaseSelect.vue.d.ts +4 -4
- package/dist/components/BaseSiteInput/BaseSiteInput.vue.d.ts +1 -1
- package/dist/components/BaseSwiper/BaseSwiper.vue.d.ts +57 -0
- package/dist/components/BaseTag/BaseTag.vue.d.ts +61 -0
- package/dist/components/BaseTextarea/BaseTextarea.vue.d.ts +5 -5
- package/dist/components/BaseToggle/BaseToggle.vue.d.ts +4 -4
- package/dist/components/BaseUpload/BaseUpload.vue.d.ts +31 -0
- package/dist/components/{Modal/Modal.vue.d.ts → BaseUpload/ImageModal.vue.d.ts} +2 -10
- package/dist/components/Toaster/Toaster.vue.d.ts +4 -4
- package/dist/composables/useModal.d.ts +7 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.js +1 -1
- package/dist/plugins/modalPlugin.d.ts +0 -13
- package/dist/sprite.svg +1 -1
- package/dist/store/modal.d.ts +154 -9
- package/example/App.vue +129 -295
- package/example/MyCustomModal.vue +37 -0
- package/package.json +1 -1
- package/src/assets/icons/add.svg +4 -0
- package/src/assets/icons/arrow-left-circle.svg +3 -0
- package/src/assets/icons/arrow-right-circle.svg +3 -0
- package/src/assets/icons/arrow-up.svg +4 -0
- package/src/assets/icons/close-circle.svg +5 -0
- package/src/assets/icons/close.svg +4 -0
- package/src/assets/icons/document-text.svg +4 -0
- package/src/assets/icons/export.svg +5 -0
- package/src/assets/icons/gallery.svg +5 -0
- package/src/assets/icons/notification-icon.svg +7 -0
- package/src/assets/icons/search-zoom-in.svg +6 -0
- package/src/assets/icons/star.svg +3 -0
- package/src/assets/icons/trash.svg +7 -0
- package/src/assets/icons/upload.svg +5 -0
- package/src/components/BaseBadge/BaseBadge.vue +188 -0
- package/src/components/BaseBadge/BaseBadgeGroup.vue +120 -0
- package/src/components/BaseBadge/README.md +127 -0
- package/src/components/BaseBreadCrumbs/BaseBreadCrumbs.vue +3 -3
- package/src/components/BaseButton/BaseButton.vue +29 -122
- package/src/components/BaseChips/BaseChips.vue +182 -0
- package/src/components/BaseChips/README.md +64 -0
- package/src/components/BaseInput/BaseInput.vue +5 -3
- package/src/components/BaseModal/BaseModal.vue +189 -0
- package/src/components/BaseOpenedListItem/BaseOpenedListItem.vue +4 -4
- package/src/components/BasePagination/BasePagination.vue +146 -123
- package/src/components/BaseSiteInput/BaseSiteInput.vue +26 -9
- package/src/components/BaseSwiper/BaseSwiper.vue +229 -0
- package/src/components/BaseTag/BaseTag.vue +245 -0
- package/src/components/BaseTag/README.md +125 -0
- package/src/components/BaseTextarea/BaseTextarea.vue +8 -14
- package/src/components/BaseUpload/BaseUpload.vue +392 -0
- package/src/components/BaseUpload/ImageModal.vue +25 -0
- package/src/composables/useModal.ts +14 -0
- package/src/index.ts +38 -19
- package/src/plugins/modalPlugin.ts +92 -76
- package/src/store/modal.ts +39 -16
- package/src/styles/root.scss +3 -0
- package/src/types/badge.d.ts +19 -0
- package/src/types/chips.d.ts +10 -0
- package/src/types/modal.d.ts +8 -0
- package/src/types/pagination.d.ts +2 -2
- package/src/types/swiper.d.ts +17 -0
- package/src/types/tag.d.ts +14 -0
- package/src/types/uploadedFile.d.ts +13 -0
- package/src/types/utils.d.ts +1 -1
- package/dist/types/index.d.ts +0 -5
- package/src/components/Modal/Modal.vue +0 -149
- package/src/components/Modal/README.md +0 -47
- package/src/types/index.ts +0 -7
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div :class="classList">
|
|
3
3
|
<div class="base-site-input__wrapper">
|
|
4
|
-
<div class="base-site-input__url">
|
|
5
|
-
|
|
4
|
+
<div class="base-site-input__url-wrapper">
|
|
5
|
+
<span class="base-site-input__url">
|
|
6
|
+
https://
|
|
7
|
+
</span>
|
|
6
8
|
</div>
|
|
7
9
|
<base-input
|
|
8
10
|
v-bind="{...$props, ...$attrs}"
|
|
@@ -90,22 +92,31 @@ watch(modelValue, (value) => {
|
|
|
90
92
|
}
|
|
91
93
|
|
|
92
94
|
&__url {
|
|
95
|
+
color: var(--primary-text-tertiary);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&__url-wrapper {
|
|
99
|
+
background: var(--bg-light);
|
|
93
100
|
display: flex;
|
|
94
101
|
align-items: center;
|
|
95
102
|
justify-content: center;
|
|
103
|
+
border-top-left-radius: var(--corner-radius-s);
|
|
96
104
|
border-top: 1px solid var(--primary-black-300);
|
|
97
105
|
border-bottom: 1px solid var(--primary-black-300);
|
|
98
106
|
border-left: 1px solid var(--primary-black-300);
|
|
99
|
-
|
|
107
|
+
border-bottom-left-radius: var(--corner-radius-s);
|
|
100
108
|
}
|
|
101
109
|
|
|
102
110
|
&.--small-size {
|
|
103
111
|
#{$input} {
|
|
104
|
-
&__url
|
|
105
|
-
height:
|
|
112
|
+
&__url-wrapper{
|
|
113
|
+
height: 40px;
|
|
106
114
|
font: var(--typography-text-m-regular);
|
|
107
115
|
border-top-left-radius: var(--corner-radius-s);
|
|
108
116
|
border-bottom-left-radius: var(--corner-radius-s);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
&__url {
|
|
109
120
|
padding: var(--spacing-s) var(--spacing-m) var(--spacing-s) var(--spacing-2l);
|
|
110
121
|
}
|
|
111
122
|
}
|
|
@@ -118,11 +129,14 @@ watch(modelValue, (value) => {
|
|
|
118
129
|
|
|
119
130
|
&.--medium-size {
|
|
120
131
|
#{$input} {
|
|
121
|
-
&__url
|
|
122
|
-
height:
|
|
132
|
+
&__url-wrapper{
|
|
133
|
+
height: 48px;
|
|
123
134
|
font: var(--typography-text-m-regular);
|
|
124
135
|
border-top-left-radius: var(--corner-radius-m);
|
|
125
136
|
border-bottom-left-radius: var(--corner-radius-m);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
&__url {
|
|
126
140
|
padding: var(--spacing-m) var(--spacing-m) var(--spacing-m) var(--spacing-2l);
|
|
127
141
|
}
|
|
128
142
|
}
|
|
@@ -135,11 +149,14 @@ watch(modelValue, (value) => {
|
|
|
135
149
|
|
|
136
150
|
&.--large-size {
|
|
137
151
|
#{$input} {
|
|
138
|
-
&__url
|
|
139
|
-
height:
|
|
152
|
+
&__url-wrapper{
|
|
153
|
+
height: 56px;
|
|
140
154
|
font: var(--typography-text-l-regular);
|
|
141
155
|
border-top-left-radius: var(--corner-radius-m);
|
|
142
156
|
border-bottom-left-radius: var(--corner-radius-m);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
&__url {
|
|
143
160
|
padding: var(--spacing-2l) var(--spacing-m) var(--spacing-2l) var(--spacing-l);
|
|
144
161
|
}
|
|
145
162
|
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="base-swiper">
|
|
3
|
+
<!-- Кнопки навигации -->
|
|
4
|
+
<button
|
|
5
|
+
:class="buttonClassList"
|
|
6
|
+
class="base-swiper__nav base-swiper__nav--prev"
|
|
7
|
+
@click="prevSlide"
|
|
8
|
+
:disabled="currentSlide === 0"
|
|
9
|
+
>
|
|
10
|
+
<base-icon
|
|
11
|
+
name="arrow-left-circle"
|
|
12
|
+
size="medium"
|
|
13
|
+
/>
|
|
14
|
+
</button>
|
|
15
|
+
<div class="base-swiper__container" ref="swiperContainer">
|
|
16
|
+
<div class="base-swiper__slides">
|
|
17
|
+
<div
|
|
18
|
+
v-for="(image, index) in images"
|
|
19
|
+
:key="index"
|
|
20
|
+
class="base-swiper__slide"
|
|
21
|
+
:style="{ transform: `translateX(-${currentSlide * 100}%)` }"
|
|
22
|
+
>
|
|
23
|
+
<img :src="image" alt="Slide" class="base-swiper__image" />
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<button
|
|
28
|
+
:class="buttonClassList"
|
|
29
|
+
class="base-swiper__nav base-swiper__nav--next"
|
|
30
|
+
@click="nextSlide"
|
|
31
|
+
:disabled="currentSlide === images.length - 1"
|
|
32
|
+
>
|
|
33
|
+
<base-icon
|
|
34
|
+
name="arrow-right-circle"
|
|
35
|
+
size="medium"
|
|
36
|
+
/>
|
|
37
|
+
</button>
|
|
38
|
+
|
|
39
|
+
<!-- Пагинация -->
|
|
40
|
+
<div class="base-swiper__pagination">
|
|
41
|
+
<base-pagination
|
|
42
|
+
:type="paginationSettings.type"
|
|
43
|
+
v-model:current-page="currentPage"
|
|
44
|
+
:total-pages="images.length"
|
|
45
|
+
:color="paginationSettings.color"
|
|
46
|
+
/>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<script setup lang="ts">
|
|
52
|
+
import { ref, onMounted, onUnmounted, watch, computed } from 'vue';
|
|
53
|
+
import BaseIcon from '../BaseIcon/BaseIcon.vue';
|
|
54
|
+
import BasePagination from '../BasePagination/BasePagination.vue';
|
|
55
|
+
import type { ICoreSwiperProps } from '../../types/swiper';
|
|
56
|
+
|
|
57
|
+
const props = withDefaults(defineProps<ICoreSwiperProps>(), {
|
|
58
|
+
images: () => [],
|
|
59
|
+
autoplay: false,
|
|
60
|
+
autoplayInterval: 3000,
|
|
61
|
+
paginationSettings: {
|
|
62
|
+
type: 'dots',
|
|
63
|
+
color: 'primary',
|
|
64
|
+
},
|
|
65
|
+
buttonSize: 'medium',
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const emit = defineEmits<{
|
|
69
|
+
(e: 'update:currentSlide', value: number): void;
|
|
70
|
+
}>();
|
|
71
|
+
|
|
72
|
+
const swiperContainer = ref<HTMLElement | null>(null);
|
|
73
|
+
const currentSlide = ref(0);
|
|
74
|
+
const currentPage = ref(1);
|
|
75
|
+
|
|
76
|
+
const buttonClassList = computed(() => [
|
|
77
|
+
`--${props.buttonSize}-size`,
|
|
78
|
+
`--color-${props.paginationSettings.color}`,
|
|
79
|
+
]);
|
|
80
|
+
|
|
81
|
+
watch(currentSlide, (newSlide) => {
|
|
82
|
+
currentPage.value = newSlide + 1;
|
|
83
|
+
emit('update:currentSlide', newSlide);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
watch(currentPage, (newPage) => {
|
|
87
|
+
currentSlide.value = newPage - 1;
|
|
88
|
+
emit('update:currentSlide', currentSlide.value);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const prevSlide = () => {
|
|
92
|
+
if (currentSlide.value > 0) {
|
|
93
|
+
currentSlide.value -= 1;
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const nextSlide = () => {
|
|
98
|
+
if (currentSlide.value < props.images.length - 1) {
|
|
99
|
+
currentSlide.value += 1;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
let autoplayIntervalId: ReturnType<typeof setInterval> | null = null;
|
|
104
|
+
|
|
105
|
+
const startAutoplay = () => {
|
|
106
|
+
if (props.autoplay && !autoplayIntervalId) {
|
|
107
|
+
autoplayIntervalId = setInterval(() => {
|
|
108
|
+
nextSlide();
|
|
109
|
+
if (currentSlide.value >= props.images.length - 1) {
|
|
110
|
+
currentSlide.value = 0; // Возвращаемся к первому слайду
|
|
111
|
+
}
|
|
112
|
+
}, props.autoplayInterval);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const stopAutoplay = () => {
|
|
117
|
+
if (autoplayIntervalId) {
|
|
118
|
+
clearInterval(autoplayIntervalId);
|
|
119
|
+
autoplayIntervalId = null;
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
onMounted(() => {
|
|
124
|
+
startAutoplay();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
onUnmounted(() => {
|
|
128
|
+
stopAutoplay();
|
|
129
|
+
});
|
|
130
|
+
</script>
|
|
131
|
+
|
|
132
|
+
<style lang="scss" scoped>
|
|
133
|
+
@import '../../styles/variables';
|
|
134
|
+
@import '../../styles/root';
|
|
135
|
+
|
|
136
|
+
.base-swiper {
|
|
137
|
+
$swiper: &;
|
|
138
|
+
|
|
139
|
+
position: relative;
|
|
140
|
+
width: 100%;
|
|
141
|
+
max-width: 640px;
|
|
142
|
+
overflow: hidden;
|
|
143
|
+
|
|
144
|
+
&__container {
|
|
145
|
+
overflow: hidden;
|
|
146
|
+
position: relative;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
&__slides {
|
|
150
|
+
display: flex;
|
|
151
|
+
width: 100%;
|
|
152
|
+
height: 100%;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
&__slide {
|
|
156
|
+
flex: 0 0 100%;
|
|
157
|
+
height: 100%;
|
|
158
|
+
display: flex;
|
|
159
|
+
justify-content: center;
|
|
160
|
+
align-items: center;
|
|
161
|
+
transition: all var(--transition);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
&__image {
|
|
165
|
+
max-width: 100%;
|
|
166
|
+
max-height: 400px;
|
|
167
|
+
object-fit: contain;
|
|
168
|
+
border-radius: var(--corner-radius-m);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
&__nav {
|
|
172
|
+
position: absolute;
|
|
173
|
+
top: 50%;
|
|
174
|
+
transform: translateY(-50%);
|
|
175
|
+
border: none;
|
|
176
|
+
cursor: pointer;
|
|
177
|
+
border-radius: 50%;
|
|
178
|
+
z-index: 10;
|
|
179
|
+
|
|
180
|
+
&--prev {
|
|
181
|
+
left: var(--spacing-m);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
&--next {
|
|
185
|
+
right: var(--spacing-m);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
&:disabled {
|
|
189
|
+
opacity: 0.5;
|
|
190
|
+
cursor: not-allowed;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
&__nav.--color-primary {
|
|
195
|
+
background: var(--primary-blue);
|
|
196
|
+
color: var(--primary-black-white);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
&__nav.--color-secondary {
|
|
200
|
+
background: var(--primary-blue-50);
|
|
201
|
+
color: var(--primary-blue-800);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
&__nav.--color-black {
|
|
205
|
+
background: #000;
|
|
206
|
+
color: var(--primary-black-white);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
&__nav.--color-white {
|
|
210
|
+
background: var(--primary-black-white);
|
|
211
|
+
color: var(--primary-black-700);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
&__nav.--medium-size {
|
|
215
|
+
padding: var(--spacing-s);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
&__nav.--large-size {
|
|
219
|
+
padding: var(--spacing-2m);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
&__pagination {
|
|
223
|
+
position: absolute;
|
|
224
|
+
bottom: 10px;
|
|
225
|
+
left: 50%;
|
|
226
|
+
transform: translateX(-50%);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
</style>
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="base-tag" :class="classList">
|
|
3
|
+
<div class="base-tag__wrapper">
|
|
4
|
+
<div class="base-tag__text">{{ text }}</div>
|
|
5
|
+
<div v-if="closable" class="base-tag__icon" @click="handleClose">
|
|
6
|
+
<base-icon name="close" size="custom" />
|
|
7
|
+
</div>
|
|
8
|
+
<div v-if="addingTag" class="base-tag__icon">
|
|
9
|
+
<base-icon name="add" size="custom" class="base-tag__add-icon" @click="handleAddTag" />
|
|
10
|
+
</div>
|
|
11
|
+
<div v-if="isHasAddTag" class="base-tag__input-wrapper">
|
|
12
|
+
<input
|
|
13
|
+
class="base-tag__input"
|
|
14
|
+
type="text"
|
|
15
|
+
v-model="inputText"
|
|
16
|
+
@input="handleInput"
|
|
17
|
+
@keypress.enter="handleCreateTag"
|
|
18
|
+
/>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
import { computed, ref } from 'vue';
|
|
26
|
+
import BaseIcon from '../BaseIcon/BaseIcon.vue';
|
|
27
|
+
import type { ICoreTagProps } from '../../types/tag';
|
|
28
|
+
import { useKitSize } from '../../composables/kit/size';
|
|
29
|
+
import { useKitColor } from '../../composables/kit/color';
|
|
30
|
+
|
|
31
|
+
const props = withDefaults(defineProps<ICoreTagProps>(), {
|
|
32
|
+
size: 'medium',
|
|
33
|
+
color: 'primary',
|
|
34
|
+
closable: false,
|
|
35
|
+
isHasAddTag: false,
|
|
36
|
+
addingTag: false,
|
|
37
|
+
text: '',
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
const emit = defineEmits<{
|
|
41
|
+
updateInput: [value: ICoreTagProps['inputText']];
|
|
42
|
+
close: [];
|
|
43
|
+
addTag: [];
|
|
44
|
+
}>();
|
|
45
|
+
|
|
46
|
+
const inputText = ref<string>(props.inputText || '');
|
|
47
|
+
|
|
48
|
+
const { sizeClassList } = useKitSize(props);
|
|
49
|
+
const { colorClassList } = useKitColor(props);
|
|
50
|
+
|
|
51
|
+
const classList = computed(() => [
|
|
52
|
+
sizeClassList.value,
|
|
53
|
+
colorClassList.value,
|
|
54
|
+
{'--adding-tag': props.addingTag},
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
const handleClose = () => {
|
|
58
|
+
emit('close');
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const handleInput = (event: Event) => {
|
|
62
|
+
const target = event.target as HTMLInputElement;
|
|
63
|
+
emit('updateInput', target.value);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const handleCreateTag = () => {
|
|
67
|
+
if (inputText.value.trim()) {
|
|
68
|
+
emit('updateInput', inputText.value.trim());
|
|
69
|
+
inputText.value = '';
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const handleAddTag = () => {
|
|
74
|
+
emit('addTag');
|
|
75
|
+
};
|
|
76
|
+
</script>
|
|
77
|
+
|
|
78
|
+
<style scoped lang="scss">
|
|
79
|
+
@import '@/styles/variables';
|
|
80
|
+
@import '@/styles/root';
|
|
81
|
+
|
|
82
|
+
.base-tag {
|
|
83
|
+
display: inline-flex;
|
|
84
|
+
align-items: center;
|
|
85
|
+
cursor: pointer;
|
|
86
|
+
|
|
87
|
+
&__wrapper {
|
|
88
|
+
display: flex;
|
|
89
|
+
align-items: center;
|
|
90
|
+
transition: all var(--transition);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
&__text {
|
|
94
|
+
white-space: nowrap;
|
|
95
|
+
overflow: hidden;
|
|
96
|
+
text-overflow: ellipsis;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
&__icon {
|
|
100
|
+
display: flex;
|
|
101
|
+
align-items: center;
|
|
102
|
+
justify-content: center;
|
|
103
|
+
margin-left: var(--spacing-xs);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
&__input-wrapper {
|
|
107
|
+
display: flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
|
|
110
|
+
.base-tag__input {
|
|
111
|
+
border: none;
|
|
112
|
+
background: transparent;
|
|
113
|
+
outline: none;
|
|
114
|
+
color: var(--primary-blue);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
&.--primary-color {
|
|
119
|
+
.base-tag__wrapper {
|
|
120
|
+
background: var(--primary-black-100);
|
|
121
|
+
color: var(--primary-black-700);
|
|
122
|
+
|
|
123
|
+
@include hover {
|
|
124
|
+
background: var(--primary-black-200);
|
|
125
|
+
color: var(--primary-black-900);
|
|
126
|
+
|
|
127
|
+
.base-tag__icon {
|
|
128
|
+
color: var(--primary-black-900);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.base-tag__icon {
|
|
134
|
+
color: var(--primary-black-500);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
&.--secondary-color {
|
|
139
|
+
.base-tag__wrapper {
|
|
140
|
+
background: var(--primary-black-white);
|
|
141
|
+
color: var(--primary-black-700); // same
|
|
142
|
+
|
|
143
|
+
@include hover {
|
|
144
|
+
background: var(--primary-black-200);
|
|
145
|
+
color: var(--primary-black-900);
|
|
146
|
+
|
|
147
|
+
.base-tag__icon {
|
|
148
|
+
color: var(--primary-black-900);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.base-tag__icon {
|
|
154
|
+
color: var(--primary-black-500);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
&.--adding-tag {
|
|
159
|
+
.base-tag__wrapper {
|
|
160
|
+
color: var(--primary-black-500);
|
|
161
|
+
|
|
162
|
+
@include hover {
|
|
163
|
+
color: var(--primary-black-900);
|
|
164
|
+
|
|
165
|
+
.base-tag__icon {
|
|
166
|
+
color: var(--primary-black-900);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
&.--extra-small-size {
|
|
174
|
+
.base-tag__text,
|
|
175
|
+
.base-tag__input {
|
|
176
|
+
font: var(--typography-text-xs-medium);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.base-tag__wrapper {
|
|
180
|
+
border-radius: var(--corner-radius-xxs);
|
|
181
|
+
padding: var(--spacing-2xs) var(--spacing-s);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.base-tag__icon,
|
|
185
|
+
.base-tag__add-icon {
|
|
186
|
+
width: 12px;
|
|
187
|
+
height: 12px;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
&.--small-size {
|
|
192
|
+
.base-tag__text,
|
|
193
|
+
.base-tag__input {
|
|
194
|
+
font: var(--typography-text-s-medium);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
.base-tag__wrapper {
|
|
198
|
+
border-radius: var(--corner-radius-xxs);
|
|
199
|
+
padding: var(--spacing-2xs) var(--spacing-s);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.base-tag__icon,
|
|
203
|
+
.base-tag__add-icon {
|
|
204
|
+
width: 14px;
|
|
205
|
+
height: 14px;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
&.--medium-size {
|
|
210
|
+
.base-tag__text,
|
|
211
|
+
.base-tag__input {
|
|
212
|
+
font: var(--typography-text-s-medium);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.base-tag__wrapper {
|
|
216
|
+
border-radius: var(--corner-radius-2xs);
|
|
217
|
+
padding: var(--spacing-xs) var(--spacing-2m);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.base-tag__icon,
|
|
221
|
+
.base-tag__add-icon {
|
|
222
|
+
width: 16px;
|
|
223
|
+
height: 16px;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
&.--large-size {
|
|
228
|
+
.base-tag__text,
|
|
229
|
+
.base-tag__input {
|
|
230
|
+
font: var(--typography-text-m-medium);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.base-tag__wrapper {
|
|
234
|
+
border-radius: var(--corner-radius-2xs);
|
|
235
|
+
padding: var(--spacing-xs) var(--spacing-2m);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.base-tag__icon,
|
|
239
|
+
.base-tag__add-icon {
|
|
240
|
+
width: 16px;
|
|
241
|
+
height: 16px;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
</style>
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Компонент BaseTag
|
|
2
|
+
|
|
3
|
+
Компонент `BaseTag` — это переиспользуемый Vue 3 компонент для отображения тегов с настраиваемым текстом, размером, цветом и поведением. Поддерживает закрываемые теги, теги с функцией добавления и поле ввода для создания новых тегов. Компонент следует методологии БЭМ для именования CSS-классов и стилизован с использованием SCSS.
|
|
4
|
+
|
|
5
|
+
## Возможности
|
|
6
|
+
|
|
7
|
+
- **Настраиваемый размер**: Поддерживает четыре варианта размеров: `extra-small`, `small`, `medium`, `large`.
|
|
8
|
+
- **Варианты цветов**: Предлагает цветовые схемы `primary` и `secondary` с эффектами наведения.
|
|
9
|
+
- **Закрываемые теги**: Опционально включает иконку закрытия для вызова события `close`.
|
|
10
|
+
- **Функция добавления тега**: Поддерживает иконку добавления для создания новых тегов.
|
|
11
|
+
- **Поле ввода**: Отображает поле ввода для создания новых тегов, если включен `isHasAddTag`.
|
|
12
|
+
- **Поддержка TypeScript**: Полностью типизирован с использованием TypeScript.
|
|
13
|
+
- **Стилизация по БЭМ**: Использует методологию БЭМ для консистентности и удобства поддержки CSS.
|
|
14
|
+
- **Композаблы**: Использует `useKitSize` и `useKitColor` для модульного управления размером и цветом.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
## Использование
|
|
18
|
+
|
|
19
|
+
Компонент `BaseTag` можно использовать в разных конфигурациях в зависимости от желаемой функциональности. Ниже приведены примеры типичных случаев использования.
|
|
20
|
+
|
|
21
|
+
### Простой тег
|
|
22
|
+
|
|
23
|
+
```vue
|
|
24
|
+
<template>
|
|
25
|
+
<base-tag text="Пример тега" />
|
|
26
|
+
</template>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Отображает тег с текстом "Пример тега" в размере `medium` и цвете `primary`.
|
|
30
|
+
|
|
31
|
+
### Закрываемый тег
|
|
32
|
+
|
|
33
|
+
```vue
|
|
34
|
+
<template>
|
|
35
|
+
<base-tag text="Закрываемый тег" closable @close="handleClose" />
|
|
36
|
+
</template>
|
|
37
|
+
|
|
38
|
+
<script setup lang="ts">
|
|
39
|
+
const handleClose = () => {
|
|
40
|
+
console.log('Тег закрыт');
|
|
41
|
+
};
|
|
42
|
+
</script>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Тег с иконкой закрытия, которая вызывает событие `close` при клике.
|
|
46
|
+
|
|
47
|
+
### Тег с полем ввода
|
|
48
|
+
|
|
49
|
+
```vue
|
|
50
|
+
<template>
|
|
51
|
+
<base-tag
|
|
52
|
+
:isHasAddTag="true"
|
|
53
|
+
v-model:inputText="tagInput"
|
|
54
|
+
@updateInput="updateInput"
|
|
55
|
+
@addTag="createTag"
|
|
56
|
+
/>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<script setup lang="ts">
|
|
60
|
+
import { ref } from 'vue';
|
|
61
|
+
|
|
62
|
+
const tagInput = ref('');
|
|
63
|
+
const updateInput = (value: string) => {
|
|
64
|
+
tagInput.value = value;
|
|
65
|
+
};
|
|
66
|
+
const createTag = () => {
|
|
67
|
+
console.log('Новый тег:', tagInput.value);
|
|
68
|
+
};
|
|
69
|
+
</script>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Тег с полем ввода для создания новых тегов. Поле ввода отображается, если `isHasAddTag` равно `true`.
|
|
73
|
+
|
|
74
|
+
### Тег с иконкой добавления
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<template>
|
|
78
|
+
<base-tag text="Добавить тег" addingTag @addTag="handleAddTag" />
|
|
79
|
+
</template>
|
|
80
|
+
|
|
81
|
+
<script setup lang="ts">
|
|
82
|
+
const handleAddTag = () => {
|
|
83
|
+
console.log('Инициировано добавление тега');
|
|
84
|
+
};
|
|
85
|
+
</script>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Тег с иконкой добавления, которая вызывает событие `addTag` при клике.
|
|
89
|
+
|
|
90
|
+
## Пропсы
|
|
91
|
+
|
|
92
|
+
| Проп | Тип | По умолчанию | Описание |
|
|
93
|
+
|--------------|----------|--------------|--------------------------------------------------------------------------|
|
|
94
|
+
| `text` | `string` | `''` | Текст, отображаемый в теге. |
|
|
95
|
+
| `size` | `string` | `'medium'` | Размер тега: `extra-small`, `small`, `medium`, `large`. |
|
|
96
|
+
| `color` | `string` | `'primary'` | Цветовая схема: `primary`, `secondary`. |
|
|
97
|
+
| `closable` | `boolean`| `false` | Включает иконку закрытия для удаления тега. |
|
|
98
|
+
| `isHasAddTag`| `boolean`| `false` | Включает поле ввода для создания нового тега. |
|
|
99
|
+
| `addingTag` | `boolean`| `false` | Включает иконку добавления тега. |
|
|
100
|
+
| `inputText` | `string` | `''` | Начальное значение поля ввода (используется с `v-model:inputText`). |
|
|
101
|
+
|
|
102
|
+
## События
|
|
103
|
+
|
|
104
|
+
| Событие | Параметры | Описание |
|
|
105
|
+
|----------------|----------------------|-------------------------------------------------------|
|
|
106
|
+
| `close` | - | Вызывается при клике на иконку закрытия. |
|
|
107
|
+
| `addTag` | - | Вызывается при клике на иконку добавления тега. |
|
|
108
|
+
| `updateInput` | `value: string` | Вызывается при изменении текста в поле ввода. |
|
|
109
|
+
|
|
110
|
+
## Стилизация
|
|
111
|
+
|
|
112
|
+
Модификаторы:
|
|
113
|
+
- `--primary-color`, `--secondary-color` — для цветовых схем.
|
|
114
|
+
- `--extra-small-size`, `--small-size`, `--medium-size`, `--large-size` — для размеров.
|
|
115
|
+
- `--adding-tag` — для стилизации тега с иконкой добавления.
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
## Зависимости
|
|
119
|
+
|
|
120
|
+
- **`BaseIcon`**: Компонент для отображения иконок (используется для иконок закрытия и добавления).
|
|
121
|
+
- **`useKitSize`**: Композабл для управления размерами.
|
|
122
|
+
- **`useKitColor`**: Композабл для управления цветами.
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|