bge-ui 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -0
- package/icons/Coin/HKD.svg +6 -0
- package/icons/Coin/USD.svg +4 -0
- package/icons/Intl/CH.svg +4 -0
- package/icons/Intl/EN.svg +14 -0
- package/icons/Intl/EUR.svg +15 -0
- package/icons/Intl/HKG.svg +8 -0
- package/icons/Intl/JPN.svg +4 -0
- package/icons/Intl/KOR.svg +6 -0
- package/icons/Intl/USA.svg +6 -0
- package/icons/Intl/VNM.svg +4 -0
- package/icons/Media/Facebook.svg +3 -0
- package/icons/Media/Instagram.svg +3 -0
- package/icons/Media/Linked.svg +3 -0
- package/icons/Media/Twitter.svg +3 -0
- package/icons/Mono/International.svg +3 -0
- package/icons/Mono/add-subtract.svg +4 -0
- package/icons/Mono/add.svg +3 -0
- package/icons/Mono/android.svg +3 -0
- package/icons/Mono/api.svg +5 -0
- package/icons/Mono/apple.svg +3 -0
- package/icons/Mono/arrow-down.svg +3 -0
- package/icons/Mono/arrow-up.svg +3 -0
- package/icons/Mono/assets.svg +4 -0
- package/icons/Mono/audit.svg +3 -0
- package/icons/Mono/bank card.svg +4 -0
- package/icons/Mono/building.svg +3 -0
- package/icons/Mono/calendar.svg +3 -0
- package/icons/Mono/check-fill.svg +3 -0
- package/icons/Mono/chevron-left.svg +3 -0
- package/icons/Mono/chevron-right-double.svg +4 -0
- package/icons/Mono/chevron-right.svg +3 -0
- package/icons/Mono/classify01.svg +3 -0
- package/icons/Mono/classify02.svg +6 -0
- package/icons/Mono/close-one.svg +4 -0
- package/icons/Mono/close.svg +3 -0
- package/icons/Mono/complete.svg +3 -0
- package/icons/Mono/copy.svg +4 -0
- package/icons/Mono/docunment.svg +5 -0
- package/icons/Mono/edit.svg +4 -0
- package/icons/Mono/email01.svg +3 -0
- package/icons/Mono/email02.svg +3 -0
- package/icons/Mono/exclamationmark-fill.svg +3 -0
- package/icons/Mono/eye-close.svg +4 -0
- package/icons/Mono/eye.svg +4 -0
- package/icons/Mono/googleplay.svg +6 -0
- package/icons/Mono/help.svg +5 -0
- package/icons/Mono/less.svg +3 -0
- package/icons/Mono/logout.svg +4 -0
- package/icons/Mono/menu.svg +5 -0
- package/icons/Mono/moon.svg +3 -0
- package/icons/Mono/more.svg +5 -0
- package/icons/Mono/notification.svg +3 -0
- package/icons/Mono/other-device.svg +5 -0
- package/icons/Mono/pic-error.svg +5 -0
- package/icons/Mono/pic.svg +4 -0
- package/icons/Mono/remove.svg +4 -0
- package/icons/Mono/route.svg +5 -0
- package/icons/Mono/safety.svg +4 -0
- package/icons/Mono/search.svg +3 -0
- package/icons/Mono/sun.svg +11 -0
- package/icons/Mono/time.svg +4 -0
- package/icons/Mono/toward-fill.svg +3 -0
- package/icons/Mono/transfer.svg +4 -0
- package/icons/Mono/trash.svg +6 -0
- package/icons/Mono/wallet.svg +4 -0
- package/icons/Mono/win.svg +6 -0
- package/icons/color/c2-all.svg +4 -0
- package/icons/color/c2-api.svg +5 -0
- package/icons/color/c2-assets.svg +4 -0
- package/icons/color/c2-bill-1.svg +4 -0
- package/icons/color/c2-bill-2.svg +5 -0
- package/icons/color/c2-card.svg +4 -0
- package/icons/color/c2-complete.svg +4 -0
- package/icons/color/c2-deal.svg +5 -0
- package/icons/color/c2-email.svg +4 -0
- package/icons/color/c2-fee.svg +6 -0
- package/icons/color/c2-google.svg +4 -0
- package/icons/color/c2-home.svg +4 -0
- package/icons/color/c2-kyc.svg +5 -0
- package/icons/color/c2-language.svg +4 -0
- package/icons/color/c2-level.svg +4 -0
- package/icons/color/c2-notification.svg +4 -0
- package/icons/color/c2-pdf.svg +4 -0
- package/icons/color/c2-phone.svg +4 -0
- package/icons/color/c2-register.svg +5 -0
- package/icons/color/c2-right-down.svg +4 -0
- package/icons/color/c2-right-up.svg +4 -0
- package/icons/color/c2-safe-shield.svg +4 -0
- package/icons/color/c2-safe.svg +4 -0
- package/icons/color/c2-traffic-cone.svg +7 -0
- package/icons/color/c2-user-every.svg +9 -0
- package/icons/color/c2-user.svg +5 -0
- package/icons/color/c3-Licensing.svg +5 -0
- package/icons/color/c3-audits.svg +7 -0
- package/icons/color/c3-card.svg +5 -0
- package/icons/color/c3-company.svg +6 -0
- package/icons/color/c3-deposit.svg +6 -0
- package/icons/color/c3-establish.svg +5 -0
- package/icons/color/c3-framework.svg +5 -0
- package/icons/color/c3-kyc.svg +7 -0
- package/icons/color/c3-not-passed.svg +7 -0
- package/icons/color/c3-pass.svg +7 -0
- package/icons/color/c3-safes.svg +8 -0
- package/icons/color/c3-trading.svg +5 -0
- package/icons/color/c3-user-every.svg +11 -0
- package/icons/color/c3-user-follow.svg +6 -0
- package/icons/color/c3-user.svg +6 -0
- package/icons/color/close-fill.svg +4 -0
- package/icons/color/completed-fill.svg +4 -0
- package/icons/color/cookie.svg +16 -0
- package/icons/color/star.svg +4 -0
- package/icons/color/success-fill.svg +11 -0
- package/icons/color/time-fill.svg +4 -0
- package/icons/color/toward-fill.svg +6 -0
- package/icons/generate.ts +152 -0
- package/package.json +37 -0
- package/src/button/index.vue +120 -0
- package/src/button/type.ts +4 -0
- package/src/dropdown/index.vue +10 -0
- package/src/form/form-item.vue +234 -0
- package/src/form/index.vue +122 -0
- package/src/icons/CoinHkd.vue +80 -0
- package/src/icons/CoinUsd.vue +72 -0
- package/src/icons/ColorC2All.vue +75 -0
- package/src/icons/ColorC2Api.vue +71 -0
- package/src/icons/ColorC2Assets.vue +72 -0
- package/src/icons/ColorC2Bill1.vue +70 -0
- package/src/icons/ColorC2Bill2.vue +68 -0
- package/src/icons/ColorC2Card.vue +67 -0
- package/src/icons/ColorC2Complete.vue +72 -0
- package/src/icons/ColorC2Deal.vue +74 -0
- package/src/icons/ColorC2Email.vue +70 -0
- package/src/icons/ColorC2Fee.vue +78 -0
- package/src/icons/ColorC2Google.vue +70 -0
- package/src/icons/ColorC2Home.vue +70 -0
- package/src/icons/ColorC2Kyc.vue +73 -0
- package/src/icons/ColorC2Language.vue +70 -0
- package/src/icons/ColorC2Level.vue +72 -0
- package/src/icons/ColorC2Notification.vue +75 -0
- package/src/icons/ColorC2Pdf.vue +73 -0
- package/src/icons/ColorC2Phone.vue +67 -0
- package/src/icons/ColorC2Register.vue +68 -0
- package/src/icons/ColorC2RightDown.vue +72 -0
- package/src/icons/ColorC2RightUp.vue +72 -0
- package/src/icons/ColorC2Safe.vue +75 -0
- package/src/icons/ColorC2SafeShield.vue +72 -0
- package/src/icons/ColorC2TrafficCone.vue +79 -0
- package/src/icons/ColorC2User.vue +79 -0
- package/src/icons/ColorC2UserEvery.vue +90 -0
- package/src/icons/ColorC3Audits.vue +76 -0
- package/src/icons/ColorC3Card.vue +68 -0
- package/src/icons/ColorC3Company.vue +69 -0
- package/src/icons/ColorC3Deposit.vue +74 -0
- package/src/icons/ColorC3Establish.vue +78 -0
- package/src/icons/ColorC3Framework.vue +71 -0
- package/src/icons/ColorC3Kyc.vue +76 -0
- package/src/icons/ColorC3Licensing.vue +71 -0
- package/src/icons/ColorC3NotPassed.vue +76 -0
- package/src/icons/ColorC3Pass.vue +78 -0
- package/src/icons/ColorC3Safes.vue +83 -0
- package/src/icons/ColorC3Trading.vue +78 -0
- package/src/icons/ColorC3User.vue +78 -0
- package/src/icons/ColorC3UserEvery.vue +98 -0
- package/src/icons/ColorC3UserFollow.vue +83 -0
- package/src/icons/ColorCloseFill.vue +74 -0
- package/src/icons/ColorCompletedFill.vue +71 -0
- package/src/icons/ColorCookie.vue +99 -0
- package/src/icons/ColorStar.vue +72 -0
- package/src/icons/ColorSuccessFill.vue +78 -0
- package/src/icons/ColorTimeFill.vue +66 -0
- package/src/icons/ColorTowardFill.vue +68 -0
- package/src/icons/IntlCh.vue +76 -0
- package/src/icons/IntlEn.vue +112 -0
- package/src/icons/IntlEur.vue +116 -0
- package/src/icons/IntlHkg.vue +98 -0
- package/src/icons/IntlJpn.vue +76 -0
- package/src/icons/IntlKor.vue +88 -0
- package/src/icons/IntlUsa.vue +83 -0
- package/src/icons/IntlVnm.vue +76 -0
- package/src/icons/MediaFacebook.vue +72 -0
- package/src/icons/MediaInstagram.vue +72 -0
- package/src/icons/MediaLinked.vue +72 -0
- package/src/icons/MediaTwitter.vue +70 -0
- package/src/icons/MonoAdd.vue +70 -0
- package/src/icons/MonoAddSubtract.vue +68 -0
- package/src/icons/MonoAndroid.vue +72 -0
- package/src/icons/MonoApi.vue +77 -0
- package/src/icons/MonoApple.vue +70 -0
- package/src/icons/MonoArrowDown.vue +67 -0
- package/src/icons/MonoArrowUp.vue +67 -0
- package/src/icons/MonoAssets.vue +78 -0
- package/src/icons/MonoAudit.vue +72 -0
- package/src/icons/MonoBankCard.vue +73 -0
- package/src/icons/MonoBuilding.vue +72 -0
- package/src/icons/MonoCalendar.vue +72 -0
- package/src/icons/MonoCheckFill.vue +72 -0
- package/src/icons/MonoChevronLeft.vue +72 -0
- package/src/icons/MonoChevronRight.vue +72 -0
- package/src/icons/MonoChevronRightDouble.vue +78 -0
- package/src/icons/MonoClassify01.vue +72 -0
- package/src/icons/MonoClassify02.vue +90 -0
- package/src/icons/MonoClose.vue +70 -0
- package/src/icons/MonoCloseOne.vue +76 -0
- package/src/icons/MonoComplete.vue +72 -0
- package/src/icons/MonoCopy.vue +73 -0
- package/src/icons/MonoDocunment.vue +74 -0
- package/src/icons/MonoEdit.vue +78 -0
- package/src/icons/MonoEmail01.vue +72 -0
- package/src/icons/MonoEmail02.vue +72 -0
- package/src/icons/MonoExclamationmarkFill.vue +72 -0
- package/src/icons/MonoEye.vue +78 -0
- package/src/icons/MonoEyeClose.vue +78 -0
- package/src/icons/MonoGoogleplay.vue +82 -0
- package/src/icons/MonoHelp.vue +77 -0
- package/src/icons/MonoInternational.vue +70 -0
- package/src/icons/MonoLess.vue +67 -0
- package/src/icons/MonoLogout.vue +71 -0
- package/src/icons/MonoMenu.vue +69 -0
- package/src/icons/MonoMoon.vue +72 -0
- package/src/icons/MonoMore.vue +69 -0
- package/src/icons/MonoNotification.vue +72 -0
- package/src/icons/MonoOtherDevice.vue +74 -0
- package/src/icons/MonoPic.vue +76 -0
- package/src/icons/MonoPicError.vue +80 -0
- package/src/icons/MonoRemove.vue +73 -0
- package/src/icons/MonoRoute.vue +69 -0
- package/src/icons/MonoSafety.vue +76 -0
- package/src/icons/MonoSearch.vue +72 -0
- package/src/icons/MonoSun.vue +95 -0
- package/src/icons/MonoTime.vue +78 -0
- package/src/icons/MonoTowardFill.vue +72 -0
- package/src/icons/MonoTransfer.vue +74 -0
- package/src/icons/MonoTrash.vue +75 -0
- package/src/icons/MonoWallet.vue +73 -0
- package/src/icons/MonoWin.vue +70 -0
- package/src/icons/index.ts +231 -0
- package/src/index.ts +50 -0
- package/src/input/index.vue +256 -0
- package/src/link/index.vue +95 -0
- package/src/message/index.vue +205 -0
- package/src/message/method.ts +138 -0
- package/src/tabs/index.vue +126 -0
- package/src/tabs/tab-pane.vue +96 -0
- package/src/tooltip/index.vue +338 -0
- package/src/tooltip/only-child.tsx +70 -0
- package/src/tooltip/usePopper.ts +578 -0
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="bge-input">
|
|
3
|
+
<div class="bge-input__wrapper" :class="{ focus: isFocus, textarea: type === 'textarea', disabled: disabled }">
|
|
4
|
+
<span class="bge-input__prefix" v-if="prefixSlot">
|
|
5
|
+
<span class="bge-input__prefix-inner">
|
|
6
|
+
<slot name="prefix" />
|
|
7
|
+
</span>
|
|
8
|
+
</span>
|
|
9
|
+
<input v-if="type !== 'textarea'" class="bge-input__inner" v-model="input" :maxlength="maxlength"
|
|
10
|
+
:disabled="disabled" :readonly="readonly" :type="type" :placeholder="placeholder" @focus="handleFocus"
|
|
11
|
+
@blur="handleBlur" @change="handleChange" @input="handleInput" />
|
|
12
|
+
<textarea v-else="type !== 'textarea'" :rows="rows" :maxlength="maxlength" class="bge-input__inner" v-model="input"
|
|
13
|
+
:disabled="disabled" :readonly="readonly" :placeholder="placeholder" @focus="handleFocus" @blur="handleBlur"
|
|
14
|
+
@change="handleChange" @input="handleInput" />
|
|
15
|
+
<span class="bge-input__suffix" :class="{ suffix: !!suffixSlot }">
|
|
16
|
+
<span class="bge-input__suffix-inner">
|
|
17
|
+
<mono-close class="bge-input__icon clear" v-show="isFocus" @mouseover.prevent="hoverClear(true)"
|
|
18
|
+
@mouseout.prevent="hoverClear(false)" @click="handelClear" size="20" />
|
|
19
|
+
<slot v-if="type !== 'textarea'" name="suffix" />
|
|
20
|
+
</span>
|
|
21
|
+
</span>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
</template>
|
|
25
|
+
<script setup lang="ts">
|
|
26
|
+
import MonoClose from "../icons/MonoClose.vue";
|
|
27
|
+
import { ref, defineProps, useSlots, defineEmits, inject, watch } from 'vue'
|
|
28
|
+
const props = defineProps({
|
|
29
|
+
type: {
|
|
30
|
+
type: String,
|
|
31
|
+
value: [
|
|
32
|
+
'text',
|
|
33
|
+
'number',
|
|
34
|
+
'textarea'
|
|
35
|
+
],
|
|
36
|
+
default: 'text'
|
|
37
|
+
},
|
|
38
|
+
modelValue: {
|
|
39
|
+
type: [String, Number],
|
|
40
|
+
default: '',
|
|
41
|
+
},
|
|
42
|
+
placeholder: String,
|
|
43
|
+
disabled: Boolean,
|
|
44
|
+
readonly: Boolean,
|
|
45
|
+
rows: {
|
|
46
|
+
default: 2,
|
|
47
|
+
type: [Number, String]
|
|
48
|
+
},
|
|
49
|
+
maxlength: {
|
|
50
|
+
type: [Number, String]
|
|
51
|
+
},
|
|
52
|
+
})
|
|
53
|
+
const emit = defineEmits([
|
|
54
|
+
'blur',
|
|
55
|
+
'focus',
|
|
56
|
+
'change',
|
|
57
|
+
'input',
|
|
58
|
+
'clear',
|
|
59
|
+
'update:modelValue'
|
|
60
|
+
])
|
|
61
|
+
const formItemContextKey = 'bge-form-item-context'
|
|
62
|
+
|
|
63
|
+
const formItemContext: any = inject(formItemContextKey, undefined)
|
|
64
|
+
|
|
65
|
+
const suffixSlot = useSlots().suffix
|
|
66
|
+
const prefixSlot = useSlots().prefix
|
|
67
|
+
const input = ref<string | number>('')
|
|
68
|
+
const isFocus = ref(false)
|
|
69
|
+
const isClearHover = ref<Boolean>(false)
|
|
70
|
+
function handleFocus() {
|
|
71
|
+
isFocus.value = true
|
|
72
|
+
emit('focus')
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function handleBlur() {
|
|
76
|
+
if (!isClearHover.value) {
|
|
77
|
+
isFocus.value = false
|
|
78
|
+
}
|
|
79
|
+
emit('blur')
|
|
80
|
+
emit('update:modelValue', input.value)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
watch(() => props.modelValue, (val) => {
|
|
84
|
+
input.value = val
|
|
85
|
+
formItemContext.validate && formItemContext.validate().catch((err: any) => (err))
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
function handleChange() {
|
|
89
|
+
emit('change', input.value)
|
|
90
|
+
emit('update:modelValue', input.value)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function handleInput() {
|
|
94
|
+
emit('input', input.value)
|
|
95
|
+
emit('update:modelValue', input.value)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function hoverClear(isHover: Boolean) {
|
|
99
|
+
isClearHover.value = isHover
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function handelClear() {
|
|
103
|
+
input.value = ''
|
|
104
|
+
isFocus.value = false
|
|
105
|
+
emit('clear', input.value)
|
|
106
|
+
emit('input', input.value)
|
|
107
|
+
emit('change', input.value)
|
|
108
|
+
emit('update:modelValue', input.value)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
</script>
|
|
112
|
+
<style lang="scss">
|
|
113
|
+
.bge-input {
|
|
114
|
+
position: relative;
|
|
115
|
+
|
|
116
|
+
.bge-input__wrapper {
|
|
117
|
+
height: 40px;
|
|
118
|
+
padding: var(--layout-x-0, 0px) var(--layout-x-4, 16px);
|
|
119
|
+
border-radius: var(--radius-small, 0px);
|
|
120
|
+
border: 1px solid transparent;
|
|
121
|
+
background: var(--bg-input, rgba(88, 126, 163, 0.08));
|
|
122
|
+
display: flex;
|
|
123
|
+
font-size: 14px;
|
|
124
|
+
align-items: center;
|
|
125
|
+
align-self: stretch;
|
|
126
|
+
|
|
127
|
+
&:hover {
|
|
128
|
+
border: 1px solid transparent;
|
|
129
|
+
background: var(--bg-input-hover, rgba(88, 126, 163, 0.12));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
&.disabled {
|
|
133
|
+
&:hover {
|
|
134
|
+
border: 1px solid transparent;
|
|
135
|
+
background: var(--bg-input, rgba(88, 126, 163, 0.08));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
&.focus {
|
|
140
|
+
border: 1px solid var(--tc-secondary, #798EA3);
|
|
141
|
+
background: transparent;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
&.textarea {
|
|
145
|
+
height: unset;
|
|
146
|
+
align-items: start;
|
|
147
|
+
position: reactive;
|
|
148
|
+
padding: 0;
|
|
149
|
+
|
|
150
|
+
.bge-input__inner {
|
|
151
|
+
padding: 8px 44px 8px 16px;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.bge-input__suffix {
|
|
155
|
+
position: absolute;
|
|
156
|
+
top: 8px;
|
|
157
|
+
right: 16px;
|
|
158
|
+
height: 24px;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.bge-input__prefix {
|
|
162
|
+
display: none;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.bge-input__inner {
|
|
168
|
+
color: var(--tc-primary, #E0E0E0);
|
|
169
|
+
caret-color: var(--tc-theme, #FFFF38);
|
|
170
|
+
font-size: inherit;
|
|
171
|
+
line-height: 24px;
|
|
172
|
+
width: 100%;
|
|
173
|
+
flex-grow: 1;
|
|
174
|
+
font-size: inherit;
|
|
175
|
+
padding: 0;
|
|
176
|
+
outline: none;
|
|
177
|
+
border: none;
|
|
178
|
+
background: none;
|
|
179
|
+
box-sizing: border-box;
|
|
180
|
+
resize: none;
|
|
181
|
+
|
|
182
|
+
::placeholder {
|
|
183
|
+
color: var(--tc-quaternary, #3B4C5C);
|
|
184
|
+
font-weight: 500;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
&:-webkit-autofill,
|
|
190
|
+
&:-webkit-autofill:hover,
|
|
191
|
+
&:-webkit-autofill:focus,
|
|
192
|
+
&:-webkit-autofill:active {
|
|
193
|
+
font-size: 14px;
|
|
194
|
+
-webkit-transition-delay: 99999s;
|
|
195
|
+
-webkit-transition: color 99999s ease-out, background-color 99999s ease-out;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.bge-input__suffix,
|
|
201
|
+
.bge-input__prefix {
|
|
202
|
+
display: inline-flex;
|
|
203
|
+
white-space: nowrap;
|
|
204
|
+
flex-shrink: 0;
|
|
205
|
+
flex-wrap: nowrap;
|
|
206
|
+
height: 100%;
|
|
207
|
+
text-align: center;
|
|
208
|
+
min-width: 20px;
|
|
209
|
+
color: var(--el-input-icon-color, var(--el-text-color-placeholder));
|
|
210
|
+
transition: all var(--el-transition-duration);
|
|
211
|
+
pointer-events: none;
|
|
212
|
+
|
|
213
|
+
&.suffix {
|
|
214
|
+
.bge-input__icon {
|
|
215
|
+
margin-right: 8px;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.bge-input__suffix-inner,
|
|
220
|
+
.bge-input__prefix-inner {
|
|
221
|
+
pointer-events: all;
|
|
222
|
+
display: inline-flex;
|
|
223
|
+
align-items: center;
|
|
224
|
+
justify-content: center;
|
|
225
|
+
color: var(--tc-tertiary, #53677A);
|
|
226
|
+
font-size: 14px;
|
|
227
|
+
font-weight: 500;
|
|
228
|
+
line-height: 24px;
|
|
229
|
+
|
|
230
|
+
.bge-input__icon {
|
|
231
|
+
height: inherit;
|
|
232
|
+
line-height: inherit;
|
|
233
|
+
display: flex;
|
|
234
|
+
justify-content: center;
|
|
235
|
+
align-items: center;
|
|
236
|
+
transition: all var(--el-transition-duration);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.clear {
|
|
240
|
+
color: #53677A;
|
|
241
|
+
cursor: pointer;
|
|
242
|
+
|
|
243
|
+
&:hover {
|
|
244
|
+
color: #E0E0E0;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.bge-input__prefix {
|
|
251
|
+
.bge-input__prefix-inner {
|
|
252
|
+
padding-right: 8px;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
</style>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a v-if="href && !disabled" :class="`bge-link bge-link--${type} ${underline ? 'underline' : ''}`" :target="target"
|
|
3
|
+
:href="href">
|
|
4
|
+
<slot></slot>
|
|
5
|
+
</a>
|
|
6
|
+
<span v-else
|
|
7
|
+
:class="`bge-link bge-link--${type} ${disabled ? 'disabled' : ''} ${underline ? 'underline' : ''} no-link`">
|
|
8
|
+
<slot></slot>
|
|
9
|
+
</span>
|
|
10
|
+
</template>
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
defineOptions({
|
|
13
|
+
name: 'Link',
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
import { defineProps } from 'vue'
|
|
17
|
+
|
|
18
|
+
defineProps({
|
|
19
|
+
target: {
|
|
20
|
+
default: '',
|
|
21
|
+
type: String,
|
|
22
|
+
},
|
|
23
|
+
type: {
|
|
24
|
+
default: 'default',
|
|
25
|
+
value: ['default', 'violet'],
|
|
26
|
+
type: String,
|
|
27
|
+
},
|
|
28
|
+
href: {
|
|
29
|
+
default: '',
|
|
30
|
+
type: String,
|
|
31
|
+
},
|
|
32
|
+
underline: {
|
|
33
|
+
default: false,
|
|
34
|
+
type: Boolean
|
|
35
|
+
},
|
|
36
|
+
disabled: {
|
|
37
|
+
default: false,
|
|
38
|
+
type: Boolean
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
</script>
|
|
42
|
+
<style lang="scss" scoped>
|
|
43
|
+
.bge-link {
|
|
44
|
+
--link-tc-color: var(--tc-tertiary, #53677A);
|
|
45
|
+
--link-tc-hover: var(--tc-secondary, #798EA3);
|
|
46
|
+
--link-tc-pressed: var(--tc-secondary, #798EA3);
|
|
47
|
+
--link-tc-disable: var(--tc-quaternary, #3B4C5C);
|
|
48
|
+
|
|
49
|
+
&.bge-link--violet {
|
|
50
|
+
--link-tc-color: var(--btn-violet, #6670FF);
|
|
51
|
+
--link-tc-hover: var(--btn-violet-hover, #7575FF);
|
|
52
|
+
--link-tc-pressed: var(--btn-violet-hover, #7575FF);
|
|
53
|
+
--link-tc-disable: var(--btn-violet-disable, #3C428F);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
text-decoration:none;
|
|
57
|
+
|
|
58
|
+
&+.bge-link {
|
|
59
|
+
margin-left: 12px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
cursor: pointer;
|
|
63
|
+
color: var(--link-tc-color);
|
|
64
|
+
|
|
65
|
+
&:hover {
|
|
66
|
+
color: var(--link-tc-hover);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
&:active {
|
|
70
|
+
color: var(--link-tc-hover);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
&.underline {
|
|
74
|
+
text-decoration-line: underline;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
&.no-link {
|
|
78
|
+
cursor: default;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
&.disabled {
|
|
82
|
+
color: var(--link-tc-disable, #3B4C5C);
|
|
83
|
+
cursor: no-drop;
|
|
84
|
+
|
|
85
|
+
&:hover {
|
|
86
|
+
color: var(--link-tc-disable, #3B4C5C);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
&:active {
|
|
90
|
+
color: var(--link-tc-disable, #3B4C5C);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
}
|
|
95
|
+
</style>
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<transition name="fade" @before-leave="onClose" @after-leave="$emit('destroy')">
|
|
3
|
+
<div v-show="visible" :id="id" ref="messageRef" :class="`bge-message ${type}`" :style="customStyle" role="alert"
|
|
4
|
+
@mouseenter="clearTimer" @mouseleave="startTimer">
|
|
5
|
+
<component v-if="icon" :is="icon" class="bge-message__icon" :size="20" />
|
|
6
|
+
<slot>
|
|
7
|
+
<p v-html="message"></p>
|
|
8
|
+
</slot>
|
|
9
|
+
</div>
|
|
10
|
+
</transition>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script setup lang="ts">
|
|
14
|
+
import MonoCheckFill from "../icons/MonoCheckFill.vue"
|
|
15
|
+
import MonoExclamationmarkFill from "../icons/MonoExclamationmarkFill.vue"
|
|
16
|
+
|
|
17
|
+
import { useEventListener, useResizeObserver, useTimeoutFn } from '@vueuse/core'
|
|
18
|
+
import { defineEmits, onMounted, ref, computed, CSSProperties, shallowReactive, render } from 'vue'
|
|
19
|
+
|
|
20
|
+
const visible = ref(false)
|
|
21
|
+
const messageRef = ref<HTMLDivElement>()
|
|
22
|
+
const icon = computed(() => {
|
|
23
|
+
const map = {
|
|
24
|
+
success: MonoCheckFill,
|
|
25
|
+
error: MonoExclamationmarkFill,
|
|
26
|
+
info: ''
|
|
27
|
+
}
|
|
28
|
+
return map[props.type]
|
|
29
|
+
})
|
|
30
|
+
const props: any = defineProps({
|
|
31
|
+
id: String,
|
|
32
|
+
type: {
|
|
33
|
+
type: String,
|
|
34
|
+
default: 'info',
|
|
35
|
+
value: [
|
|
36
|
+
'success',
|
|
37
|
+
'error',
|
|
38
|
+
'info',
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
offset: {
|
|
42
|
+
type: Number,
|
|
43
|
+
default: 64,
|
|
44
|
+
},
|
|
45
|
+
stopTimer: Number,
|
|
46
|
+
duration: Number,
|
|
47
|
+
message: {
|
|
48
|
+
type: [Object, String]
|
|
49
|
+
},
|
|
50
|
+
onClose: Function,
|
|
51
|
+
instances: Array
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
let stopTimer: (() => void) | undefined = undefined
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
function startTimer() {
|
|
58
|
+
if (props.duration === 0) return
|
|
59
|
+
; ({ stop: stopTimer } = useTimeoutFn(() => {
|
|
60
|
+
close()
|
|
61
|
+
}, props.duration))
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function close() {
|
|
65
|
+
visible.value = false
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function clearTimer() {
|
|
69
|
+
stopTimer?.()
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const getInstance = (id: string) => {
|
|
73
|
+
const idx = props.instances.findIndex((instance) => instance.id === id)
|
|
74
|
+
const current = props.instances[idx]
|
|
75
|
+
let prev: any | undefined
|
|
76
|
+
if (idx > 0) {
|
|
77
|
+
prev = props.instances[idx - 1]
|
|
78
|
+
}
|
|
79
|
+
return { current, prev }
|
|
80
|
+
}
|
|
81
|
+
const getLastOffset = (id: string): number => {
|
|
82
|
+
const { prev } = getInstance(id)
|
|
83
|
+
if (!prev) return 0
|
|
84
|
+
return prev.vm.exposed!.bottom.value
|
|
85
|
+
}
|
|
86
|
+
const getOffsetOrSpace = (id: string, offset: number) => {
|
|
87
|
+
const idx = props.instances.findIndex((instance) => instance.id === id)
|
|
88
|
+
return idx > 0 ? 12 : offset
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const height = ref(0)
|
|
92
|
+
const lastOffset = computed(() => getLastOffset(props.id))
|
|
93
|
+
const offset = computed(
|
|
94
|
+
() => getOffsetOrSpace(props.id, props.offset) + lastOffset.value
|
|
95
|
+
)
|
|
96
|
+
const bottom = computed((): number => height.value + offset.value)
|
|
97
|
+
|
|
98
|
+
const customStyle = computed<CSSProperties>(() => {
|
|
99
|
+
return {
|
|
100
|
+
top: `${offset.value}px`,
|
|
101
|
+
zIndex: 3000,
|
|
102
|
+
}
|
|
103
|
+
})
|
|
104
|
+
onMounted(() => {
|
|
105
|
+
visible.value = true
|
|
106
|
+
startTimer()
|
|
107
|
+
})
|
|
108
|
+
const emit = defineEmits([
|
|
109
|
+
'destroy'
|
|
110
|
+
])
|
|
111
|
+
|
|
112
|
+
useResizeObserver(messageRef, () => {
|
|
113
|
+
height.value = messageRef.value!.getBoundingClientRect().height
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
defineExpose({
|
|
117
|
+
visible,
|
|
118
|
+
bottom,
|
|
119
|
+
close,
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
</script>
|
|
123
|
+
<style lang="scss" >
|
|
124
|
+
.bge-message {
|
|
125
|
+
position: fixed;
|
|
126
|
+
left: 50%;
|
|
127
|
+
top: 60px;
|
|
128
|
+
transform: translateX(-50%);
|
|
129
|
+
display: inline-block;
|
|
130
|
+
max-width: 320px;
|
|
131
|
+
transition: opacity 0.3s, transform 0.4s, top 0.4s;
|
|
132
|
+
padding: var(--layout-x-2, 8px) var(--layout-x-4, 16px);
|
|
133
|
+
overflow: hidden;
|
|
134
|
+
color: var(--persistent-white, #FFF);
|
|
135
|
+
/* shadow1 */
|
|
136
|
+
box-shadow: 0px 12px 40px 0px rgba(0, 0, 0, 0.08);
|
|
137
|
+
|
|
138
|
+
&.info {
|
|
139
|
+
background: var(--bg-tooltip, #53677A);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
&.error {
|
|
143
|
+
background: var(--bg-red, #D14770);
|
|
144
|
+
|
|
145
|
+
p {
|
|
146
|
+
width: calc(100% - 24px)
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
&.success {
|
|
151
|
+
background: var(--bg-green, #00A389);
|
|
152
|
+
|
|
153
|
+
p {
|
|
154
|
+
width: calc(100% - 24px)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.bge-message__icon {
|
|
159
|
+
vertical-align: middle;
|
|
160
|
+
margin-right: 4px;
|
|
161
|
+
flex-shrink: 0;
|
|
162
|
+
display: inline-block;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
p {
|
|
166
|
+
padding: 0;
|
|
167
|
+
margin: 0;
|
|
168
|
+
display: inline-block;
|
|
169
|
+
width: 100%;
|
|
170
|
+
vertical-align: middle;
|
|
171
|
+
white-space: nowrap;
|
|
172
|
+
overflow: hidden;
|
|
173
|
+
color: var(--persistent-white, #FFF);
|
|
174
|
+
text-overflow: ellipsis;
|
|
175
|
+
font-size: 14px;
|
|
176
|
+
font-style: normal;
|
|
177
|
+
font-weight: 400;
|
|
178
|
+
line-height: 24px;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
&.fade-enter-active {
|
|
183
|
+
transition: opacity 0.1s cubic-bezier(0, 0, 1, 1);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
&.fade-leave-active {
|
|
187
|
+
transition: all 0.3s cubic-bezier(0.34, 0.69, 0.1, 1);
|
|
188
|
+
|
|
189
|
+
svg,
|
|
190
|
+
p {
|
|
191
|
+
opacity: 0.3;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
&.fade-leave-to {
|
|
196
|
+
opacity: 0;
|
|
197
|
+
height: 0;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
&.fade-enter-from {
|
|
201
|
+
opacity: 0;
|
|
202
|
+
transform: translate(-50%, -100%);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
</style>
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { createVNode, render, shallowReactive, isVNode } from 'vue'
|
|
2
|
+
import MessageConstructor from './index.vue'
|
|
3
|
+
import type { AppContext } from 'vue'
|
|
4
|
+
|
|
5
|
+
const messageTypes = ['success', 'info', 'error'] as const
|
|
6
|
+
|
|
7
|
+
const messageDefaults = {
|
|
8
|
+
customClass: '',
|
|
9
|
+
center: false,
|
|
10
|
+
dangerouslyUseHTMLString: false,
|
|
11
|
+
duration: 3000,
|
|
12
|
+
icon: undefined,
|
|
13
|
+
id: '',
|
|
14
|
+
message: '',
|
|
15
|
+
onClose: undefined,
|
|
16
|
+
showClose: false,
|
|
17
|
+
type: 'info',
|
|
18
|
+
offset: 64,
|
|
19
|
+
zIndex: 0,
|
|
20
|
+
grouping: false,
|
|
21
|
+
repeatNum: 1,
|
|
22
|
+
appendTo: document.body,
|
|
23
|
+
} as const
|
|
24
|
+
|
|
25
|
+
let seed = 1
|
|
26
|
+
|
|
27
|
+
const instances: any[] = shallowReactive([])
|
|
28
|
+
|
|
29
|
+
const closeMessage = (instance: any) => {
|
|
30
|
+
const idx = instances.indexOf(instance)
|
|
31
|
+
if (idx === -1) return
|
|
32
|
+
|
|
33
|
+
instances.splice(idx, 1)
|
|
34
|
+
const { handler } = instance
|
|
35
|
+
handler.close()
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function isFunction(functionToCheck: any) {
|
|
39
|
+
return functionToCheck && {}.toString.call(functionToCheck) === '[object Function]';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function createMessage(_options: any = {}, context?: AppContext | null) {
|
|
43
|
+
const id = `message_${seed++}`
|
|
44
|
+
const normalized = {
|
|
45
|
+
...messageDefaults,
|
|
46
|
+
..._options,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const { appendTo, ...options } = normalized
|
|
50
|
+
|
|
51
|
+
const userOnClose = normalized.onClose
|
|
52
|
+
const container = document.createElement('div')
|
|
53
|
+
const props = {
|
|
54
|
+
...options,
|
|
55
|
+
// now the zIndex will be used inside the message.vue component instead of here.
|
|
56
|
+
// zIndex: nextIndex() + normalized.zIndex
|
|
57
|
+
id,
|
|
58
|
+
onClose: () => {
|
|
59
|
+
userOnClose?.()
|
|
60
|
+
closeMessage(instance)
|
|
61
|
+
},
|
|
62
|
+
instances,
|
|
63
|
+
|
|
64
|
+
// clean message element preventing mem leak
|
|
65
|
+
onDestroy: () => {
|
|
66
|
+
// since the element is destroy, then the VNode should be collected by GC as well
|
|
67
|
+
// we do not want cause any mem leak because we have returned vm as a reference to users
|
|
68
|
+
// so that we manually set it to false.
|
|
69
|
+
render(null, container)
|
|
70
|
+
},
|
|
71
|
+
}
|
|
72
|
+
const vnode = createVNode(
|
|
73
|
+
MessageConstructor,
|
|
74
|
+
props,
|
|
75
|
+
isFunction(props.message) || isVNode(props.message)
|
|
76
|
+
? {
|
|
77
|
+
default: isFunction(props.message)
|
|
78
|
+
? props.message
|
|
79
|
+
: () => props.message,
|
|
80
|
+
}
|
|
81
|
+
: null
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
vnode.appContext = context || message._context
|
|
85
|
+
render(vnode, container)
|
|
86
|
+
// instances will remove this item when close function gets called. So we do not need to worry about it.
|
|
87
|
+
appendTo.appendChild(container.firstElementChild!)
|
|
88
|
+
const vm = vnode.component!
|
|
89
|
+
|
|
90
|
+
const handler: any = {
|
|
91
|
+
close: () => {
|
|
92
|
+
vm.exposed!.visible.value = false
|
|
93
|
+
},
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const instance: any = {
|
|
97
|
+
id,
|
|
98
|
+
vnode,
|
|
99
|
+
vm,
|
|
100
|
+
handler,
|
|
101
|
+
props: (vnode.component as any).props,
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return instance
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const message: any &
|
|
108
|
+
Partial<any> & { _context: AppContext | null } = (options = {}, context: any) => {
|
|
109
|
+
if (instances.length >= 10) {
|
|
110
|
+
return { close: () => undefined }
|
|
111
|
+
}
|
|
112
|
+
const normalized: any = typeof options === 'string' ? { message: options } : { ...options }
|
|
113
|
+
const instance = createMessage(normalized, context)
|
|
114
|
+
|
|
115
|
+
instances.push(instance)
|
|
116
|
+
return instance.handler
|
|
117
|
+
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
messageTypes.forEach((type: any) => {
|
|
121
|
+
message[type] = (options = {}, appContext: any) => {
|
|
122
|
+
const normalized: any = typeof options === 'string' ? { message: options } : { ...options }
|
|
123
|
+
return message({ ...normalized, type }, appContext)
|
|
124
|
+
}
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
export function closeAll(type?: any): void {
|
|
128
|
+
for (const instance of instances) {
|
|
129
|
+
if (!type || type === instance.props.type) {
|
|
130
|
+
instance.handler.close()
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
message.closeAll = closeAll
|
|
136
|
+
message._context = null
|
|
137
|
+
|
|
138
|
+
export default message as any
|