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.
Files changed (247) hide show
  1. package/README.md +18 -0
  2. package/icons/Coin/HKD.svg +6 -0
  3. package/icons/Coin/USD.svg +4 -0
  4. package/icons/Intl/CH.svg +4 -0
  5. package/icons/Intl/EN.svg +14 -0
  6. package/icons/Intl/EUR.svg +15 -0
  7. package/icons/Intl/HKG.svg +8 -0
  8. package/icons/Intl/JPN.svg +4 -0
  9. package/icons/Intl/KOR.svg +6 -0
  10. package/icons/Intl/USA.svg +6 -0
  11. package/icons/Intl/VNM.svg +4 -0
  12. package/icons/Media/Facebook.svg +3 -0
  13. package/icons/Media/Instagram.svg +3 -0
  14. package/icons/Media/Linked.svg +3 -0
  15. package/icons/Media/Twitter.svg +3 -0
  16. package/icons/Mono/International.svg +3 -0
  17. package/icons/Mono/add-subtract.svg +4 -0
  18. package/icons/Mono/add.svg +3 -0
  19. package/icons/Mono/android.svg +3 -0
  20. package/icons/Mono/api.svg +5 -0
  21. package/icons/Mono/apple.svg +3 -0
  22. package/icons/Mono/arrow-down.svg +3 -0
  23. package/icons/Mono/arrow-up.svg +3 -0
  24. package/icons/Mono/assets.svg +4 -0
  25. package/icons/Mono/audit.svg +3 -0
  26. package/icons/Mono/bank card.svg +4 -0
  27. package/icons/Mono/building.svg +3 -0
  28. package/icons/Mono/calendar.svg +3 -0
  29. package/icons/Mono/check-fill.svg +3 -0
  30. package/icons/Mono/chevron-left.svg +3 -0
  31. package/icons/Mono/chevron-right-double.svg +4 -0
  32. package/icons/Mono/chevron-right.svg +3 -0
  33. package/icons/Mono/classify01.svg +3 -0
  34. package/icons/Mono/classify02.svg +6 -0
  35. package/icons/Mono/close-one.svg +4 -0
  36. package/icons/Mono/close.svg +3 -0
  37. package/icons/Mono/complete.svg +3 -0
  38. package/icons/Mono/copy.svg +4 -0
  39. package/icons/Mono/docunment.svg +5 -0
  40. package/icons/Mono/edit.svg +4 -0
  41. package/icons/Mono/email01.svg +3 -0
  42. package/icons/Mono/email02.svg +3 -0
  43. package/icons/Mono/exclamationmark-fill.svg +3 -0
  44. package/icons/Mono/eye-close.svg +4 -0
  45. package/icons/Mono/eye.svg +4 -0
  46. package/icons/Mono/googleplay.svg +6 -0
  47. package/icons/Mono/help.svg +5 -0
  48. package/icons/Mono/less.svg +3 -0
  49. package/icons/Mono/logout.svg +4 -0
  50. package/icons/Mono/menu.svg +5 -0
  51. package/icons/Mono/moon.svg +3 -0
  52. package/icons/Mono/more.svg +5 -0
  53. package/icons/Mono/notification.svg +3 -0
  54. package/icons/Mono/other-device.svg +5 -0
  55. package/icons/Mono/pic-error.svg +5 -0
  56. package/icons/Mono/pic.svg +4 -0
  57. package/icons/Mono/remove.svg +4 -0
  58. package/icons/Mono/route.svg +5 -0
  59. package/icons/Mono/safety.svg +4 -0
  60. package/icons/Mono/search.svg +3 -0
  61. package/icons/Mono/sun.svg +11 -0
  62. package/icons/Mono/time.svg +4 -0
  63. package/icons/Mono/toward-fill.svg +3 -0
  64. package/icons/Mono/transfer.svg +4 -0
  65. package/icons/Mono/trash.svg +6 -0
  66. package/icons/Mono/wallet.svg +4 -0
  67. package/icons/Mono/win.svg +6 -0
  68. package/icons/color/c2-all.svg +4 -0
  69. package/icons/color/c2-api.svg +5 -0
  70. package/icons/color/c2-assets.svg +4 -0
  71. package/icons/color/c2-bill-1.svg +4 -0
  72. package/icons/color/c2-bill-2.svg +5 -0
  73. package/icons/color/c2-card.svg +4 -0
  74. package/icons/color/c2-complete.svg +4 -0
  75. package/icons/color/c2-deal.svg +5 -0
  76. package/icons/color/c2-email.svg +4 -0
  77. package/icons/color/c2-fee.svg +6 -0
  78. package/icons/color/c2-google.svg +4 -0
  79. package/icons/color/c2-home.svg +4 -0
  80. package/icons/color/c2-kyc.svg +5 -0
  81. package/icons/color/c2-language.svg +4 -0
  82. package/icons/color/c2-level.svg +4 -0
  83. package/icons/color/c2-notification.svg +4 -0
  84. package/icons/color/c2-pdf.svg +4 -0
  85. package/icons/color/c2-phone.svg +4 -0
  86. package/icons/color/c2-register.svg +5 -0
  87. package/icons/color/c2-right-down.svg +4 -0
  88. package/icons/color/c2-right-up.svg +4 -0
  89. package/icons/color/c2-safe-shield.svg +4 -0
  90. package/icons/color/c2-safe.svg +4 -0
  91. package/icons/color/c2-traffic-cone.svg +7 -0
  92. package/icons/color/c2-user-every.svg +9 -0
  93. package/icons/color/c2-user.svg +5 -0
  94. package/icons/color/c3-Licensing.svg +5 -0
  95. package/icons/color/c3-audits.svg +7 -0
  96. package/icons/color/c3-card.svg +5 -0
  97. package/icons/color/c3-company.svg +6 -0
  98. package/icons/color/c3-deposit.svg +6 -0
  99. package/icons/color/c3-establish.svg +5 -0
  100. package/icons/color/c3-framework.svg +5 -0
  101. package/icons/color/c3-kyc.svg +7 -0
  102. package/icons/color/c3-not-passed.svg +7 -0
  103. package/icons/color/c3-pass.svg +7 -0
  104. package/icons/color/c3-safes.svg +8 -0
  105. package/icons/color/c3-trading.svg +5 -0
  106. package/icons/color/c3-user-every.svg +11 -0
  107. package/icons/color/c3-user-follow.svg +6 -0
  108. package/icons/color/c3-user.svg +6 -0
  109. package/icons/color/close-fill.svg +4 -0
  110. package/icons/color/completed-fill.svg +4 -0
  111. package/icons/color/cookie.svg +16 -0
  112. package/icons/color/star.svg +4 -0
  113. package/icons/color/success-fill.svg +11 -0
  114. package/icons/color/time-fill.svg +4 -0
  115. package/icons/color/toward-fill.svg +6 -0
  116. package/icons/generate.ts +152 -0
  117. package/package.json +37 -0
  118. package/src/button/index.vue +120 -0
  119. package/src/button/type.ts +4 -0
  120. package/src/dropdown/index.vue +10 -0
  121. package/src/form/form-item.vue +234 -0
  122. package/src/form/index.vue +122 -0
  123. package/src/icons/CoinHkd.vue +80 -0
  124. package/src/icons/CoinUsd.vue +72 -0
  125. package/src/icons/ColorC2All.vue +75 -0
  126. package/src/icons/ColorC2Api.vue +71 -0
  127. package/src/icons/ColorC2Assets.vue +72 -0
  128. package/src/icons/ColorC2Bill1.vue +70 -0
  129. package/src/icons/ColorC2Bill2.vue +68 -0
  130. package/src/icons/ColorC2Card.vue +67 -0
  131. package/src/icons/ColorC2Complete.vue +72 -0
  132. package/src/icons/ColorC2Deal.vue +74 -0
  133. package/src/icons/ColorC2Email.vue +70 -0
  134. package/src/icons/ColorC2Fee.vue +78 -0
  135. package/src/icons/ColorC2Google.vue +70 -0
  136. package/src/icons/ColorC2Home.vue +70 -0
  137. package/src/icons/ColorC2Kyc.vue +73 -0
  138. package/src/icons/ColorC2Language.vue +70 -0
  139. package/src/icons/ColorC2Level.vue +72 -0
  140. package/src/icons/ColorC2Notification.vue +75 -0
  141. package/src/icons/ColorC2Pdf.vue +73 -0
  142. package/src/icons/ColorC2Phone.vue +67 -0
  143. package/src/icons/ColorC2Register.vue +68 -0
  144. package/src/icons/ColorC2RightDown.vue +72 -0
  145. package/src/icons/ColorC2RightUp.vue +72 -0
  146. package/src/icons/ColorC2Safe.vue +75 -0
  147. package/src/icons/ColorC2SafeShield.vue +72 -0
  148. package/src/icons/ColorC2TrafficCone.vue +79 -0
  149. package/src/icons/ColorC2User.vue +79 -0
  150. package/src/icons/ColorC2UserEvery.vue +90 -0
  151. package/src/icons/ColorC3Audits.vue +76 -0
  152. package/src/icons/ColorC3Card.vue +68 -0
  153. package/src/icons/ColorC3Company.vue +69 -0
  154. package/src/icons/ColorC3Deposit.vue +74 -0
  155. package/src/icons/ColorC3Establish.vue +78 -0
  156. package/src/icons/ColorC3Framework.vue +71 -0
  157. package/src/icons/ColorC3Kyc.vue +76 -0
  158. package/src/icons/ColorC3Licensing.vue +71 -0
  159. package/src/icons/ColorC3NotPassed.vue +76 -0
  160. package/src/icons/ColorC3Pass.vue +78 -0
  161. package/src/icons/ColorC3Safes.vue +83 -0
  162. package/src/icons/ColorC3Trading.vue +78 -0
  163. package/src/icons/ColorC3User.vue +78 -0
  164. package/src/icons/ColorC3UserEvery.vue +98 -0
  165. package/src/icons/ColorC3UserFollow.vue +83 -0
  166. package/src/icons/ColorCloseFill.vue +74 -0
  167. package/src/icons/ColorCompletedFill.vue +71 -0
  168. package/src/icons/ColorCookie.vue +99 -0
  169. package/src/icons/ColorStar.vue +72 -0
  170. package/src/icons/ColorSuccessFill.vue +78 -0
  171. package/src/icons/ColorTimeFill.vue +66 -0
  172. package/src/icons/ColorTowardFill.vue +68 -0
  173. package/src/icons/IntlCh.vue +76 -0
  174. package/src/icons/IntlEn.vue +112 -0
  175. package/src/icons/IntlEur.vue +116 -0
  176. package/src/icons/IntlHkg.vue +98 -0
  177. package/src/icons/IntlJpn.vue +76 -0
  178. package/src/icons/IntlKor.vue +88 -0
  179. package/src/icons/IntlUsa.vue +83 -0
  180. package/src/icons/IntlVnm.vue +76 -0
  181. package/src/icons/MediaFacebook.vue +72 -0
  182. package/src/icons/MediaInstagram.vue +72 -0
  183. package/src/icons/MediaLinked.vue +72 -0
  184. package/src/icons/MediaTwitter.vue +70 -0
  185. package/src/icons/MonoAdd.vue +70 -0
  186. package/src/icons/MonoAddSubtract.vue +68 -0
  187. package/src/icons/MonoAndroid.vue +72 -0
  188. package/src/icons/MonoApi.vue +77 -0
  189. package/src/icons/MonoApple.vue +70 -0
  190. package/src/icons/MonoArrowDown.vue +67 -0
  191. package/src/icons/MonoArrowUp.vue +67 -0
  192. package/src/icons/MonoAssets.vue +78 -0
  193. package/src/icons/MonoAudit.vue +72 -0
  194. package/src/icons/MonoBankCard.vue +73 -0
  195. package/src/icons/MonoBuilding.vue +72 -0
  196. package/src/icons/MonoCalendar.vue +72 -0
  197. package/src/icons/MonoCheckFill.vue +72 -0
  198. package/src/icons/MonoChevronLeft.vue +72 -0
  199. package/src/icons/MonoChevronRight.vue +72 -0
  200. package/src/icons/MonoChevronRightDouble.vue +78 -0
  201. package/src/icons/MonoClassify01.vue +72 -0
  202. package/src/icons/MonoClassify02.vue +90 -0
  203. package/src/icons/MonoClose.vue +70 -0
  204. package/src/icons/MonoCloseOne.vue +76 -0
  205. package/src/icons/MonoComplete.vue +72 -0
  206. package/src/icons/MonoCopy.vue +73 -0
  207. package/src/icons/MonoDocunment.vue +74 -0
  208. package/src/icons/MonoEdit.vue +78 -0
  209. package/src/icons/MonoEmail01.vue +72 -0
  210. package/src/icons/MonoEmail02.vue +72 -0
  211. package/src/icons/MonoExclamationmarkFill.vue +72 -0
  212. package/src/icons/MonoEye.vue +78 -0
  213. package/src/icons/MonoEyeClose.vue +78 -0
  214. package/src/icons/MonoGoogleplay.vue +82 -0
  215. package/src/icons/MonoHelp.vue +77 -0
  216. package/src/icons/MonoInternational.vue +70 -0
  217. package/src/icons/MonoLess.vue +67 -0
  218. package/src/icons/MonoLogout.vue +71 -0
  219. package/src/icons/MonoMenu.vue +69 -0
  220. package/src/icons/MonoMoon.vue +72 -0
  221. package/src/icons/MonoMore.vue +69 -0
  222. package/src/icons/MonoNotification.vue +72 -0
  223. package/src/icons/MonoOtherDevice.vue +74 -0
  224. package/src/icons/MonoPic.vue +76 -0
  225. package/src/icons/MonoPicError.vue +80 -0
  226. package/src/icons/MonoRemove.vue +73 -0
  227. package/src/icons/MonoRoute.vue +69 -0
  228. package/src/icons/MonoSafety.vue +76 -0
  229. package/src/icons/MonoSearch.vue +72 -0
  230. package/src/icons/MonoSun.vue +95 -0
  231. package/src/icons/MonoTime.vue +78 -0
  232. package/src/icons/MonoTowardFill.vue +72 -0
  233. package/src/icons/MonoTransfer.vue +74 -0
  234. package/src/icons/MonoTrash.vue +75 -0
  235. package/src/icons/MonoWallet.vue +73 -0
  236. package/src/icons/MonoWin.vue +70 -0
  237. package/src/icons/index.ts +231 -0
  238. package/src/index.ts +50 -0
  239. package/src/input/index.vue +256 -0
  240. package/src/link/index.vue +95 -0
  241. package/src/message/index.vue +205 -0
  242. package/src/message/method.ts +138 -0
  243. package/src/tabs/index.vue +126 -0
  244. package/src/tabs/tab-pane.vue +96 -0
  245. package/src/tooltip/index.vue +338 -0
  246. package/src/tooltip/only-child.tsx +70 -0
  247. 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