vue-chat-kit 0.3.10 → 0.3.11

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 (79) hide show
  1. package/dist/vue-chat-kit.css +1 -1
  2. package/dist/vue-chat-kit.es.js +4426 -2819
  3. package/dist/vue-chat-kit.umd.js +1 -1
  4. package/package.json +1 -1
  5. package/src/components/AvatarCrop.vue +16 -127
  6. package/src/components/ChatPanel.vue +491 -2675
  7. package/src/components/EmojiPicker.vue +2 -73
  8. package/src/components/chat/ChatWindow.vue +177 -0
  9. package/src/components/chat/ContentList.vue +300 -0
  10. package/src/components/chat/ContextMenu.vue +32 -0
  11. package/src/components/chat/GroupSidebar.vue +284 -0
  12. package/src/components/chat/MainArea.vue +87 -0
  13. package/src/components/chat/Sidebar.vue +52 -0
  14. package/src/components/chat/dialogs/AddFriendDialog.vue +62 -0
  15. package/src/components/chat/dialogs/CreateGroupDialog.vue +86 -0
  16. package/src/components/chat/dialogs/GroupDetailDialog.vue +132 -0
  17. package/src/components/ui/Button.vue +190 -0
  18. package/src/components/ui/Dialog.vue +194 -0
  19. package/src/components/ui/Empty.vue +66 -0
  20. package/src/components/ui/Input.vue +166 -0
  21. package/src/components/ui/Message.vue +186 -0
  22. package/src/components/ui/MessageBox.vue +143 -0
  23. package/src/components/ui/MessageManager.vue +92 -0
  24. package/src/components/ui/Switch.vue +65 -0
  25. package/src/components/ui/Tag.vue +68 -0
  26. package/src/components/ui/icons/ArrowDown.vue +5 -0
  27. package/src/components/ui/icons/ArrowRight.vue +5 -0
  28. package/src/components/ui/icons/Bell.vue +6 -0
  29. package/src/components/ui/icons/Camera.vue +6 -0
  30. package/src/components/ui/icons/ChatDotRound.vue +5 -0
  31. package/src/components/ui/icons/Check.vue +5 -0
  32. package/src/components/ui/icons/CircleCheck.vue +6 -0
  33. package/src/components/ui/icons/Clock.vue +6 -0
  34. package/src/components/ui/icons/Close.vue +5 -0
  35. package/src/components/ui/icons/Delete.vue +8 -0
  36. package/src/components/ui/icons/Edit.vue +6 -0
  37. package/src/components/ui/icons/Folder.vue +5 -0
  38. package/src/components/ui/icons/Minus.vue +5 -0
  39. package/src/components/ui/icons/Monitor.vue +7 -0
  40. package/src/components/ui/icons/Moon.vue +5 -0
  41. package/src/components/ui/icons/Picture.vue +7 -0
  42. package/src/components/ui/icons/Plus.vue +5 -0
  43. package/src/components/ui/icons/Search.vue +6 -0
  44. package/src/components/ui/icons/Setting.vue +6 -0
  45. package/src/components/ui/icons/Sunny.vue +6 -0
  46. package/src/components/ui/icons/User.vue +6 -0
  47. package/src/components/ui/icons/UserFilled.vue +6 -0
  48. package/src/components/ui/icons/Warning.vue +5 -0
  49. package/src/components/ui/icons/index.js +24 -0
  50. package/src/components/ui/index.js +10 -0
  51. package/src/composables/useFriendChat.js +10 -14
  52. package/src/composables/useGroupChat.js +140 -48
  53. package/src/composables/useMessage.js +21 -0
  54. package/src/composables/useMessageBox.js +98 -0
  55. package/src/composables/useTheme.js +140 -0
  56. package/src/config/index.js +1 -0
  57. package/src/const/index.js +1 -0
  58. package/src/const/theme.js +19 -0
  59. package/src/core/api.js +13 -2
  60. package/src/index.js +5 -5
  61. package/src/styles/_base.scss +38 -0
  62. package/src/styles/_variables.scss +43 -0
  63. package/src/styles/components/_add-friend-dialog.scss +45 -0
  64. package/src/styles/components/_avatar-crop.scss +120 -0
  65. package/src/styles/components/_chat-panel.scss +546 -0
  66. package/src/styles/components/_chat-window.scss +239 -0
  67. package/src/styles/components/_content-list.scss +260 -0
  68. package/src/styles/components/_context-menu.scss +35 -0
  69. package/src/styles/components/_create-group-dialog.scss +78 -0
  70. package/src/styles/components/_dialogs.scss +226 -0
  71. package/src/styles/components/_emoji-picker.scss +74 -0
  72. package/src/styles/components/_group-detail-dialog.scss +110 -0
  73. package/src/styles/components/_group-sidebar.scss +278 -0
  74. package/src/styles/components/_main-area.scss +94 -0
  75. package/src/styles/components/_sidebar.scss +83 -0
  76. package/src/styles/index.scss +18 -0
  77. package/src/styles/themes/_dark.scss +68 -0
  78. package/src/styles/themes/_index.scss +7 -0
  79. package/src/styles/themes/_light.scss +69 -0
@@ -0,0 +1,166 @@
1
+ <template>
2
+ <div class="vc-input" :class="{ 'vc-input--focus': isFocused }">
3
+ <span v-if="$slots.prefix" class="vc-input__prefix">
4
+ <slot name="prefix"></slot>
5
+ </span>
6
+ <input
7
+ v-if="type !== 'textarea'"
8
+ ref="inputRef"
9
+ :type="type"
10
+ :value="modelValue"
11
+ :placeholder="placeholder"
12
+ :disabled="disabled"
13
+ :maxlength="maxlength"
14
+ @input="handleInput"
15
+ @focus="handleFocus"
16
+ @blur="handleBlur"
17
+ @keyup="handleKeyup"
18
+ class="vc-input__inner"
19
+ />
20
+ <textarea
21
+ v-else
22
+ ref="textareaRef"
23
+ :value="modelValue"
24
+ :placeholder="placeholder"
25
+ :disabled="disabled"
26
+ :maxlength="maxlength"
27
+ :rows="rows"
28
+ @input="handleInput"
29
+ @focus="handleFocus"
30
+ @blur="handleBlur"
31
+ class="vc-input__inner"
32
+ ></textarea>
33
+ <span v-if="$slots.suffix" class="vc-input__suffix">
34
+ <slot name="suffix"></slot>
35
+ </span>
36
+ </div>
37
+ </template>
38
+
39
+ <script setup>
40
+ import { ref, computed } from 'vue'
41
+
42
+ const props = defineProps({
43
+ modelValue: {
44
+ type: [String, Number],
45
+ default: ''
46
+ },
47
+ type: {
48
+ type: String,
49
+ default: 'text',
50
+ validator: (val) => ['text', 'password', 'email', 'number', 'textarea'].includes(val)
51
+ },
52
+ placeholder: {
53
+ type: String,
54
+ default: ''
55
+ },
56
+ disabled: {
57
+ type: Boolean,
58
+ default: false
59
+ },
60
+ maxlength: {
61
+ type: Number,
62
+ default: null
63
+ },
64
+ rows: {
65
+ type: Number,
66
+ default: 3
67
+ }
68
+ })
69
+
70
+ const emit = defineEmits(['update:modelValue', 'input', 'focus', 'blur', 'keyup'])
71
+
72
+ const inputRef = ref(null)
73
+ const textareaRef = ref(null)
74
+ const isFocused = ref(false)
75
+
76
+ const handleInput = (e) => {
77
+ const value = e.target.value
78
+ emit('update:modelValue', value)
79
+ emit('input', value)
80
+ }
81
+
82
+ const handleFocus = (e) => {
83
+ isFocused.value = true
84
+ emit('focus', e)
85
+ }
86
+
87
+ const handleBlur = (e) => {
88
+ isFocused.value = false
89
+ emit('blur', e)
90
+ }
91
+
92
+ const handleKeyup = (e) => {
93
+ emit('keyup', e)
94
+ }
95
+
96
+ const focus = () => {
97
+ if (inputRef.value) {
98
+ inputRef.value.focus()
99
+ }
100
+ if (textareaRef.value) {
101
+ textareaRef.value.focus()
102
+ }
103
+ }
104
+
105
+ defineExpose({ focus })
106
+ </script>
107
+
108
+ <style scoped lang="scss">
109
+ .vc-input {
110
+ display: flex;
111
+ align-items: center;
112
+ width: 100%;
113
+ background-color: var(--vck-bg);
114
+ border: 1px solid var(--vck-border);
115
+ border-radius: var(--vck-radius);
116
+ padding: var(--vck-space-sm) var(--vck-space);
117
+ transition: all var(--vck-transition-fast);
118
+
119
+ &--focus {
120
+ border-color: var(--vck-primary);
121
+ }
122
+
123
+ &:hover:not(.vc-input--disabled) {
124
+ border-color: var(--vck-border-strong);
125
+ }
126
+
127
+ &__inner {
128
+ flex: 1;
129
+ width: 100%;
130
+ border: none;
131
+ background: transparent;
132
+ color: var(--vck-text-primary);
133
+ font-size: 14px;
134
+ line-height: 1.5;
135
+ outline: none;
136
+ resize: none;
137
+ font-family: inherit;
138
+
139
+ &::placeholder {
140
+ color: var(--vck-text-placeholder);
141
+ }
142
+
143
+ &:disabled {
144
+ color: var(--vck-text-muted);
145
+ cursor: not-allowed;
146
+ opacity: 0.7;
147
+ }
148
+ }
149
+
150
+ &__prefix,
151
+ &__suffix {
152
+ display: inline-flex;
153
+ align-items: center;
154
+ color: var(--vck-text-muted);
155
+ font-size: 14px;
156
+
157
+ &:not(:empty) + .vc-input__inner {
158
+ margin-left: var(--vck-space-xs);
159
+ }
160
+
161
+ .vc-input__inner:not(:empty) + & {
162
+ margin-left: var(--vck-space-xs);
163
+ }
164
+ }
165
+ }
166
+ </style>
@@ -0,0 +1,186 @@
1
+ <template>
2
+ <Transition name="vc-message-fade">
3
+ <div
4
+ v-if="visible"
5
+ class="vc-message"
6
+ :class="[`vc-message--${type}`]"
7
+ :style="style"
8
+ >
9
+ <span v-if="$slots.icon || icon" class="vc-message__icon">
10
+ <slot name="icon">
11
+ <component v-if="icon" :is="icon"></component>
12
+ </slot>
13
+ </span>
14
+ <span v-if="$slots.default" class="vc-message__content">
15
+ <slot>{{ content }}</slot>
16
+ </span>
17
+ <span v-else-if="content" class="vc-message__content">
18
+ {{ content }}
19
+ </span>
20
+ <button v-if="showClose" class="vc-message__close" @click="handleClose">
21
+ <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
22
+ <path d="M6 6L18 18M18 6L6 18" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
23
+ </svg>
24
+ </button>
25
+ </div>
26
+ </Transition>
27
+ </template>
28
+
29
+ <script setup>
30
+ import { ref, computed, onMounted } from 'vue'
31
+
32
+ const props = defineProps({
33
+ visible: {
34
+ type: Boolean,
35
+ default: false
36
+ },
37
+ content: {
38
+ type: String,
39
+ default: ''
40
+ },
41
+ type: {
42
+ type: String,
43
+ default: 'info',
44
+ validator: (val) => ['success', 'warning', 'danger', 'error', 'info'].includes(val)
45
+ },
46
+ icon: {
47
+ type: [String, Object],
48
+ default: null
49
+ },
50
+ showClose: {
51
+ type: Boolean,
52
+ default: false
53
+ },
54
+ duration: {
55
+ type: Number,
56
+ default: 3000
57
+ },
58
+ onClose: {
59
+ type: Function,
60
+ default: null
61
+ },
62
+ offset: {
63
+ type: Number,
64
+ default: 20
65
+ },
66
+ zIndex: {
67
+ type: Number,
68
+ default: 3000
69
+ }
70
+ })
71
+
72
+ const emit = defineEmits(['close'])
73
+
74
+ const style = computed(() => ({
75
+ top: `${props.offset}px`,
76
+ zIndex: props.zIndex
77
+ }))
78
+
79
+ const handleClose = () => {
80
+ emit('close')
81
+ if (props.onClose) {
82
+ props.onClose()
83
+ }
84
+ }
85
+
86
+ onMounted(() => {
87
+ if (props.duration > 0) {
88
+ setTimeout(() => {
89
+ handleClose()
90
+ }, props.duration)
91
+ }
92
+ })
93
+ </script>
94
+
95
+ <style scoped lang="scss">
96
+ .vc-message {
97
+ display: inline-flex;
98
+ align-items: center;
99
+ gap: var(--vck-space-sm);
100
+ padding: var(--vck-space-sm) var(--vck-space-md);
101
+ background-color: var(--vck-bg);
102
+ border: 1px solid var(--vck-border);
103
+ border-radius: var(--vck-radius);
104
+ box-shadow: var(--vck-shadow-light);
105
+ color: var(--vck-text-primary);
106
+ font-size: 14px;
107
+ position: fixed;
108
+ left: 50%;
109
+ transform: translateX(-50%);
110
+ transition: opacity var(--vck-transition-fast), transform var(--vck-transition-fast);
111
+ z-index: 3000;
112
+
113
+ &--success {
114
+ background-color: var(--vck-bg-active);
115
+ border-color: var(--vck-primary);
116
+ color: var(--vck-primary);
117
+ }
118
+
119
+ &--warning {
120
+ background-color: rgba(245, 158, 11, 0.1);
121
+ border-color: var(--vck-warning);
122
+ color: var(--vck-warning);
123
+ }
124
+
125
+ &--danger,
126
+ &--error {
127
+ background-color: rgba(239, 68, 68, 0.1);
128
+ border-color: var(--vck-danger);
129
+ color: var(--vck-danger);
130
+ }
131
+
132
+ &--info {
133
+ background-color: rgba(59, 130, 246, 0.1);
134
+ border-color: var(--vck-info);
135
+ color: var(--vck-info);
136
+ }
137
+
138
+ &__icon {
139
+ display: inline-flex;
140
+ font-size: 16px;
141
+ }
142
+
143
+ &__content {
144
+ line-height: 1.5;
145
+ }
146
+
147
+ &__close {
148
+ display: inline-flex;
149
+ align-items: center;
150
+ justify-content: center;
151
+ width: 16px;
152
+ height: 16px;
153
+ padding: 0;
154
+ margin-left: var(--vck-space-xs);
155
+ border: none;
156
+ background: none;
157
+ color: var(--vck-text-muted);
158
+ cursor: pointer;
159
+ transition: color var(--vck-transition-fast);
160
+
161
+ &:hover {
162
+ color: var(--vck-text-primary);
163
+ }
164
+
165
+ svg {
166
+ width: 12px;
167
+ height: 12px;
168
+ }
169
+ }
170
+ }
171
+
172
+ .vc-message-fade-enter-active,
173
+ .vc-message-fade-leave-active {
174
+ transition: opacity var(--vck-transition-fast), transform var(--vck-transition-fast);
175
+ }
176
+
177
+ .vc-message-fade-enter-from {
178
+ opacity: 0;
179
+ transform: translate(-50%, -20px);
180
+ }
181
+
182
+ .vc-message-fade-leave-to {
183
+ opacity: 0;
184
+ transform: translate(-50%, -20px);
185
+ }
186
+ </style>
@@ -0,0 +1,143 @@
1
+ <template>
2
+ <Dialog
3
+ :model-value="visible"
4
+ :title="title"
5
+ :width="width"
6
+ :show-close="showClose"
7
+ :close-on-click-modal="closeOnClickModal"
8
+ @close="handleClose"
9
+ @update:model-value="handleUpdateVisible"
10
+ >
11
+ <div class="vc-message-box">
12
+ <div v-if="$slots.default || message" class="vc-message-box__content">
13
+ <slot>{{ message }}</slot>
14
+ </div>
15
+ <div v-if="$slots.input" class="vc-message-box__input">
16
+ <slot name="input"></slot>
17
+ </div>
18
+ </div>
19
+ <template #footer>
20
+ <Button v-if="showCancelButton" @click="handleCancel">{{ cancelButtonText }}</Button>
21
+ <Button v-if="showConfirmButton" type="primary" @click="handleConfirm" :loading="confirmLoading">
22
+ {{ confirmButtonText }}
23
+ </Button>
24
+ </template>
25
+ </Dialog>
26
+ </template>
27
+
28
+ <script setup>
29
+ import { ref } from 'vue'
30
+ import Dialog from './Dialog.vue'
31
+ import Button from './Button.vue'
32
+
33
+ const props = defineProps({
34
+ title: {
35
+ type: String,
36
+ default: '提示'
37
+ },
38
+ message: {
39
+ type: String,
40
+ default: ''
41
+ },
42
+ showClose: {
43
+ type: Boolean,
44
+ default: true
45
+ },
46
+ showCancelButton: {
47
+ type: Boolean,
48
+ default: true
49
+ },
50
+ showConfirmButton: {
51
+ type: Boolean,
52
+ default: true
53
+ },
54
+ cancelButtonText: {
55
+ type: String,
56
+ default: '取消'
57
+ },
58
+ confirmButtonText: {
59
+ type: String,
60
+ default: '确定'
61
+ },
62
+ closeOnClickModal: {
63
+ type: Boolean,
64
+ default: true
65
+ },
66
+ width: {
67
+ type: [String, Number],
68
+ default: '420px'
69
+ }
70
+ })
71
+
72
+ const emit = defineEmits(['confirm', 'cancel', 'close', 'update:modelValue'])
73
+
74
+ const visible = ref(false)
75
+ const confirmLoading = ref(false)
76
+ let resolveCallback = null
77
+ let rejectCallback = null
78
+
79
+ const open = () => {
80
+ visible.value = true
81
+ return new Promise((resolve, reject) => {
82
+ resolveCallback = resolve
83
+ rejectCallback = reject
84
+ })
85
+ }
86
+
87
+ const close = () => {
88
+ visible.value = false
89
+ confirmLoading.value = false
90
+ }
91
+
92
+ const handleUpdateVisible = (val) => {
93
+ visible.value = val
94
+ if (!val) {
95
+ emit('update:modelValue', val)
96
+ emit('close')
97
+ }
98
+ }
99
+
100
+ const handleClose = () => {
101
+ visible.value = false
102
+ emit('close')
103
+ if (rejectCallback) {
104
+ rejectCallback('cancel')
105
+ }
106
+ }
107
+
108
+ const handleCancel = () => {
109
+ visible.value = false
110
+ emit('cancel')
111
+ if (rejectCallback) {
112
+ rejectCallback('cancel')
113
+ }
114
+ }
115
+
116
+ const handleConfirm = () => {
117
+ confirmLoading.value = true
118
+ emit('confirm')
119
+ if (resolveCallback) {
120
+ resolveCallback('confirm')
121
+ }
122
+ setTimeout(() => {
123
+ visible.value = false
124
+ confirmLoading.value = false
125
+ }, 300)
126
+ }
127
+
128
+ defineExpose({ open, close })
129
+ </script>
130
+
131
+ <style scoped lang="scss">
132
+ .vc-message-box {
133
+ &__content {
134
+ font-size: 14px;
135
+ color: var(--vck-text-primary);
136
+ line-height: 1.6;
137
+ }
138
+
139
+ &__input {
140
+ margin-top: var(--vck-space-md);
141
+ }
142
+ }
143
+ </style>
@@ -0,0 +1,92 @@
1
+ <template>
2
+ <div class="vc-message-manager">
3
+ <Message
4
+ v-for="(message, index) in messages"
5
+ :key="message.id"
6
+ :visible="message.visible"
7
+ :content="message.content"
8
+ :type="message.type"
9
+ :icon="message.icon"
10
+ :show-close="message.showClose"
11
+ :duration="message.duration"
12
+ :offset="calculateOffset(index)"
13
+ :on-close="() => handleClose(message.id)"
14
+ @close="() => handleClose(message.id)"
15
+ />
16
+ </div>
17
+ </template>
18
+
19
+ <script setup>
20
+ import { ref, computed, provide, inject } from 'vue'
21
+ import Message from './Message.vue'
22
+
23
+ const MESSAGE_MANAGER_KEY = Symbol('messageManager')
24
+
25
+ const messages = ref([])
26
+ let nextId = 1
27
+
28
+ const calculateOffset = (index) => {
29
+ return 20 + index * 56
30
+ }
31
+
32
+ const handleClose = (id) => {
33
+ const index = messages.value.findIndex(m => m.id === id)
34
+ if (index !== -1) {
35
+ messages.value[index].visible = false
36
+ setTimeout(() => {
37
+ const currentIndex = messages.value.findIndex(m => m.id === id)
38
+ if (currentIndex !== -1) {
39
+ messages.value.splice(currentIndex, 1)
40
+ }
41
+ }, 300)
42
+ }
43
+ }
44
+
45
+ const showMessage = (options) => {
46
+ const {
47
+ content,
48
+ type = 'info',
49
+ icon = null,
50
+ showClose = false,
51
+ duration = 3000
52
+ } = typeof options === 'string' ? { content: options } : options
53
+
54
+ const id = nextId++
55
+ messages.value.push({
56
+ id,
57
+ visible: true,
58
+ content,
59
+ type,
60
+ icon,
61
+ showClose,
62
+ duration
63
+ })
64
+
65
+ return () => handleClose(id)
66
+ }
67
+
68
+ const methods = {
69
+ show: showMessage,
70
+ success: (content, options = {}) => showMessage({ content, type: 'success', ...options }),
71
+ warning: (content, options = {}) => showMessage({ content, type: 'warning', ...options }),
72
+ error: (content, options = {}) => showMessage({ content, type: 'error', ...options }),
73
+ info: (content, options = {}) => showMessage({ content, type: 'info', ...options })
74
+ }
75
+
76
+ provide(MESSAGE_MANAGER_KEY, methods)
77
+ </script>
78
+
79
+ <style scoped>
80
+ .vc-message-manager {
81
+ position: fixed;
82
+ top: 0;
83
+ left: 0;
84
+ right: 0;
85
+ pointer-events: none;
86
+ z-index: 3000;
87
+ }
88
+
89
+ .vc-message-manager :deep(.vc-message) {
90
+ pointer-events: auto;
91
+ }
92
+ </style>
@@ -0,0 +1,65 @@
1
+ <template>
2
+ <div
3
+ :class="['vc-switch', { 'vc-switch-active': modelValue, 'vc-switch-disabled': disabled }]"
4
+ @click="handleClick"
5
+ >
6
+ <div class="vc-switch-handle"></div>
7
+ </div>
8
+ </template>
9
+
10
+ <script setup>
11
+ const props = defineProps({
12
+ modelValue: {
13
+ type: Boolean,
14
+ default: false
15
+ },
16
+ disabled: {
17
+ type: Boolean,
18
+ default: false
19
+ }
20
+ })
21
+
22
+ const emit = defineEmits(['update:modelValue'])
23
+
24
+ const handleClick = () => {
25
+ if (props.disabled) return
26
+ emit('update:modelValue', !props.modelValue)
27
+ }
28
+ </script>
29
+
30
+ <style scoped lang="scss">
31
+ .vc-switch {
32
+ position: relative;
33
+ display: inline-flex;
34
+ align-items: center;
35
+ width: 44px;
36
+ height: 22px;
37
+ border-radius: 11px;
38
+ background-color: var(--vck-text-muted);
39
+ transition: background-color 0.3s;
40
+ cursor: pointer;
41
+
42
+ &.vc-switch-active {
43
+ background-color: var(--vck-primary);
44
+ }
45
+
46
+ &.vc-switch-disabled {
47
+ opacity: 0.6;
48
+ cursor: not-allowed;
49
+ }
50
+
51
+ .vc-switch-handle {
52
+ position: absolute;
53
+ left: 2px;
54
+ width: 18px;
55
+ height: 18px;
56
+ border-radius: 50%;
57
+ background-color: var(--vck-bg);
58
+ transition: transform 0.3s;
59
+ }
60
+
61
+ &.vc-switch-active .vc-switch-handle {
62
+ transform: translateX(22px);
63
+ }
64
+ }
65
+ </style>
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <span
3
+ class="vc-tag"
4
+ :class="[
5
+ `vc-tag--${type}`,
6
+ { 'vc-tag--disabled': disabled }
7
+ ]"
8
+ >
9
+ <slot></slot>
10
+ </span>
11
+ </template>
12
+
13
+ <script setup>
14
+ const props = defineProps({
15
+ type: {
16
+ type: String,
17
+ default: 'default',
18
+ validator: (val) => ['default', 'success', 'warning', 'danger', 'info'].includes(val)
19
+ },
20
+ disabled: {
21
+ type: Boolean,
22
+ default: false
23
+ }
24
+ })
25
+ </script>
26
+
27
+ <style scoped lang="scss">
28
+ .vc-tag {
29
+ display: inline-flex;
30
+ align-items: center;
31
+ padding: 2px 8px;
32
+ font-size: 12px;
33
+ border-radius: 4px;
34
+ background-color: var(--vck-bg-panel);
35
+ color: var(--vck-text-secondary);
36
+ border: 1px solid var(--vck-border);
37
+ transition: all var(--vck-transition-fast);
38
+
39
+ &--success {
40
+ background-color: rgba(16, 185, 129, 0.1);
41
+ color: var(--vck-success);
42
+ border-color: rgba(16, 185, 129, 0.3);
43
+ }
44
+
45
+ &--warning {
46
+ background-color: rgba(245, 158, 11, 0.1);
47
+ color: var(--vck-warning);
48
+ border-color: rgba(245, 158, 11, 0.3);
49
+ }
50
+
51
+ &--danger {
52
+ background-color: rgba(239, 68, 68, 0.1);
53
+ color: var(--vck-danger);
54
+ border-color: rgba(239, 68, 68, 0.3);
55
+ }
56
+
57
+ &--info {
58
+ background-color: rgba(59, 130, 246, 0.1);
59
+ color: var(--vck-info);
60
+ border-color: rgba(59, 130, 246, 0.3);
61
+ }
62
+
63
+ &--disabled {
64
+ opacity: 0.5;
65
+ cursor: not-allowed;
66
+ }
67
+ }
68
+ </style>