little-dizzy 2.1.0 → 2.3.0
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/little-dizzy.css +1 -1
- package/dist/little-dizzy.js +435 -126
- package/dist/little-dizzy.umd.cjs +120 -2
- package/dist/vite.svg +25 -1
- package/package.json +63 -59
- package/src/components/Message.vue +156 -0
- package/src/components/Modal.vue +27 -17
- package/src/components/custom/Lztext.vue +170 -0
- package/src/components/custom/index.js +6 -2
- package/src/components/custom/lzbutton.vue +5 -5
- package/src/components/custom/lztheme.vue +241 -0
- package/src/components/message.js +238 -0
- package/src/index.js +4 -1
- package/src/snippets/presets/index.js +4 -2
- package/src/snippets/presets/message.js +45 -0
- package/src/styles/_variables.scss +8 -0
- package/src/styles/tailwind.css +1 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="Lztext-wrapper">
|
|
3
|
+
<div class="loader-wrapper">
|
|
4
|
+
<span class="loader-letter">G</span>
|
|
5
|
+
<span class="loader-letter">e</span>
|
|
6
|
+
<span class="loader-letter">n</span>
|
|
7
|
+
<span class="loader-letter">e</span>
|
|
8
|
+
<span class="loader-letter">r</span>
|
|
9
|
+
<span class="loader-letter">a</span>
|
|
10
|
+
<span class="loader-letter">t</span>
|
|
11
|
+
<span class="loader-letter">i</span>
|
|
12
|
+
<span class="loader-letter">n</span>
|
|
13
|
+
<span class="loader-letter">g</span>
|
|
14
|
+
<div class="loader"></div>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script setup>
|
|
20
|
+
/**
|
|
21
|
+
* 渐变文字动画
|
|
22
|
+
*
|
|
23
|
+
* 由 LittleDizzy Demo 自动生成
|
|
24
|
+
* @component Lztext
|
|
25
|
+
*/
|
|
26
|
+
defineOptions({
|
|
27
|
+
name: 'Lztext'
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<style scoped>
|
|
33
|
+
.loader-wrapper {
|
|
34
|
+
position: relative;
|
|
35
|
+
display: flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
height: 120px;
|
|
39
|
+
width: auto;
|
|
40
|
+
margin: 2rem;
|
|
41
|
+
|
|
42
|
+
font-family: "Poppins", sans-serif;
|
|
43
|
+
font-size: 1.6em;
|
|
44
|
+
font-weight: 600;
|
|
45
|
+
user-select: none;
|
|
46
|
+
color: #fff;
|
|
47
|
+
|
|
48
|
+
scale: 2;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.loader {
|
|
52
|
+
position: absolute;
|
|
53
|
+
top: 0;
|
|
54
|
+
left: 0;
|
|
55
|
+
height: 100%;
|
|
56
|
+
width: 100%;
|
|
57
|
+
z-index: 1;
|
|
58
|
+
|
|
59
|
+
background-color: transparent;
|
|
60
|
+
mask: repeating-linear-gradient(
|
|
61
|
+
90deg,
|
|
62
|
+
transparent 0,
|
|
63
|
+
transparent 6px,
|
|
64
|
+
black 7px,
|
|
65
|
+
black 8px
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.loader::after {
|
|
70
|
+
content: "";
|
|
71
|
+
position: absolute;
|
|
72
|
+
top: 0;
|
|
73
|
+
left: 0;
|
|
74
|
+
width: 100%;
|
|
75
|
+
height: 100%;
|
|
76
|
+
|
|
77
|
+
background-image: radial-gradient(circle at 50% 50%, #ff0 0%, transparent 50%),
|
|
78
|
+
radial-gradient(circle at 45% 45%, #f00 0%, transparent 45%),
|
|
79
|
+
radial-gradient(circle at 55% 55%, #0ff 0%, transparent 45%),
|
|
80
|
+
radial-gradient(circle at 45% 55%, #0f0 0%, transparent 45%),
|
|
81
|
+
radial-gradient(circle at 55% 45%, #00f 0%, transparent 45%);
|
|
82
|
+
mask: radial-gradient(
|
|
83
|
+
circle at 50% 50%,
|
|
84
|
+
transparent 0%,
|
|
85
|
+
transparent 10%,
|
|
86
|
+
black 25%
|
|
87
|
+
);
|
|
88
|
+
animation:
|
|
89
|
+
transform-animation 2s infinite alternate,
|
|
90
|
+
opacity-animation 4s infinite;
|
|
91
|
+
animation-timing-function: cubic-bezier(0.6, 0.8, 0.5, 1);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
@keyframes transform-animation {
|
|
95
|
+
0% {
|
|
96
|
+
transform: translate(-55%);
|
|
97
|
+
}
|
|
98
|
+
100% {
|
|
99
|
+
transform: translate(55%);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@keyframes opacity-animation {
|
|
104
|
+
0%,
|
|
105
|
+
100% {
|
|
106
|
+
opacity: 0;
|
|
107
|
+
}
|
|
108
|
+
15% {
|
|
109
|
+
opacity: 1;
|
|
110
|
+
}
|
|
111
|
+
65% {
|
|
112
|
+
opacity: 0;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.loader-letter {
|
|
117
|
+
display: inline-block;
|
|
118
|
+
opacity: 0;
|
|
119
|
+
animation: loader-letter-anim 4s infinite linear;
|
|
120
|
+
z-index: 2;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.loader-letter:nth-child(1) {
|
|
124
|
+
animation-delay: 0.1s;
|
|
125
|
+
}
|
|
126
|
+
.loader-letter:nth-child(2) {
|
|
127
|
+
animation-delay: 0.205s;
|
|
128
|
+
}
|
|
129
|
+
.loader-letter:nth-child(3) {
|
|
130
|
+
animation-delay: 0.31s;
|
|
131
|
+
}
|
|
132
|
+
.loader-letter:nth-child(4) {
|
|
133
|
+
animation-delay: 0.415s;
|
|
134
|
+
}
|
|
135
|
+
.loader-letter:nth-child(5) {
|
|
136
|
+
animation-delay: 0.521s;
|
|
137
|
+
}
|
|
138
|
+
.loader-letter:nth-child(6) {
|
|
139
|
+
animation-delay: 0.626s;
|
|
140
|
+
}
|
|
141
|
+
.loader-letter:nth-child(7) {
|
|
142
|
+
animation-delay: 0.731s;
|
|
143
|
+
}
|
|
144
|
+
.loader-letter:nth-child(8) {
|
|
145
|
+
animation-delay: 0.837s;
|
|
146
|
+
}
|
|
147
|
+
.loader-letter:nth-child(9) {
|
|
148
|
+
animation-delay: 0.942s;
|
|
149
|
+
}
|
|
150
|
+
.loader-letter:nth-child(10) {
|
|
151
|
+
animation-delay: 1.047s;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
@keyframes loader-letter-anim {
|
|
155
|
+
0% {
|
|
156
|
+
opacity: 0;
|
|
157
|
+
}
|
|
158
|
+
5% {
|
|
159
|
+
opacity: 1;
|
|
160
|
+
text-shadow: 0 0 4px #fff;
|
|
161
|
+
transform: scale(1.1) translateY(-2px);
|
|
162
|
+
}
|
|
163
|
+
20% {
|
|
164
|
+
opacity: 0.2;
|
|
165
|
+
}
|
|
166
|
+
100% {
|
|
167
|
+
opacity: 0;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
</style>
|
|
@@ -6,13 +6,17 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import Lzbutton from './lzbutton.vue'
|
|
9
|
+
import Lztext from './Lztext.vue'
|
|
10
|
+
import Lztheme from './lztheme.vue'
|
|
9
11
|
|
|
10
12
|
// 自定义组件导出
|
|
11
13
|
export const customComponents = {
|
|
12
|
-
Lzbutton
|
|
14
|
+
Lzbutton,
|
|
15
|
+
Lztext,
|
|
16
|
+
Lztheme
|
|
13
17
|
}
|
|
14
18
|
|
|
15
19
|
// 单独导出每个组件
|
|
16
|
-
export { Lzbutton }
|
|
20
|
+
export { Lzbutton, Lztext, Lztheme }
|
|
17
21
|
|
|
18
22
|
export default customComponents
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="lzbutton-wrapper">
|
|
3
3
|
<button class="button">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 24">
|
|
5
|
+
<path d="m18 0 8 12 10-8-4 20H4L0 4l10 8 8-12z"></path>
|
|
6
|
+
</svg>
|
|
7
|
+
<slot>Unlock Pro</slot>
|
|
8
8
|
</button>
|
|
9
9
|
</div>
|
|
10
10
|
</template>
|
|
@@ -36,7 +36,7 @@ defineOptions({
|
|
|
36
36
|
color: #fff;
|
|
37
37
|
border: none;
|
|
38
38
|
background-position: left center;
|
|
39
|
-
box-shadow: 0 30px 10px -20px rgba(0,0,0
|
|
39
|
+
box-shadow: 0 30px 10px -20px rgba(0, 0, 0, .2);
|
|
40
40
|
transition: background .3s ease;
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="lztheme-wrapper">
|
|
3
|
+
<label for="theme" class="theme">
|
|
4
|
+
<span class="theme__toggle-wrap">
|
|
5
|
+
<input id="theme" class="theme__toggle" type="checkbox" role="switch" name="theme" value="dark">
|
|
6
|
+
<span class="theme__fill"></span>
|
|
7
|
+
<span class="theme__icon">
|
|
8
|
+
<span class="theme__icon-part"></span>
|
|
9
|
+
<span class="theme__icon-part"></span>
|
|
10
|
+
<span class="theme__icon-part"></span>
|
|
11
|
+
<span class="theme__icon-part"></span>
|
|
12
|
+
<span class="theme__icon-part"></span>
|
|
13
|
+
<span class="theme__icon-part"></span>
|
|
14
|
+
<span class="theme__icon-part"></span>
|
|
15
|
+
<span class="theme__icon-part"></span>
|
|
16
|
+
<span class="theme__icon-part"></span>
|
|
17
|
+
</span>
|
|
18
|
+
</span>
|
|
19
|
+
</label>
|
|
20
|
+
</div>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<script setup>
|
|
24
|
+
/**
|
|
25
|
+
* 主题切换
|
|
26
|
+
*
|
|
27
|
+
* 由 LittleDizzy Demo 自动生成
|
|
28
|
+
* @component Lztheme
|
|
29
|
+
*/
|
|
30
|
+
defineOptions({
|
|
31
|
+
name: 'Lztheme'
|
|
32
|
+
})
|
|
33
|
+
</script>
|
|
34
|
+
|
|
35
|
+
<style scoped>
|
|
36
|
+
/* Default */
|
|
37
|
+
.theme {
|
|
38
|
+
display: flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
-webkit-tap-highlight-color: transparent;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.theme__fill,
|
|
44
|
+
.theme__icon {
|
|
45
|
+
transition: 0.3s;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.theme__fill {
|
|
49
|
+
background-color: var(--bg);
|
|
50
|
+
display: block;
|
|
51
|
+
mix-blend-mode: difference;
|
|
52
|
+
position: fixed;
|
|
53
|
+
inset: 0;
|
|
54
|
+
height: 100%;
|
|
55
|
+
transform: translateX(-100%);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.theme__icon,
|
|
59
|
+
.theme__toggle {
|
|
60
|
+
z-index: 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.theme__icon,
|
|
64
|
+
.theme__icon-part {
|
|
65
|
+
position: absolute;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.theme__icon {
|
|
69
|
+
display: block;
|
|
70
|
+
top: 0.5em;
|
|
71
|
+
left: 0.5em;
|
|
72
|
+
width: 1.5em;
|
|
73
|
+
height: 1.5em;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.theme__icon-part {
|
|
77
|
+
border-radius: 50%;
|
|
78
|
+
box-shadow: 0.4em -0.4em 0 0.5em hsl(0,0%,100%) inset;
|
|
79
|
+
top: calc(50% - 0.5em);
|
|
80
|
+
left: calc(50% - 0.5em);
|
|
81
|
+
width: 1em;
|
|
82
|
+
height: 1em;
|
|
83
|
+
transition: box-shadow var(--transDur) ease-in-out,
|
|
84
|
+
opacity var(--transDur) ease-in-out,
|
|
85
|
+
transform var(--transDur) ease-in-out;
|
|
86
|
+
transform: scale(0.5);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.theme__icon-part ~ .theme__icon-part {
|
|
90
|
+
background-color: hsl(0,0%,100%);
|
|
91
|
+
border-radius: 0.05em;
|
|
92
|
+
top: 50%;
|
|
93
|
+
left: calc(50% - 0.05em);
|
|
94
|
+
transform: rotate(0deg) translateY(0.5em);
|
|
95
|
+
transform-origin: 50% 0;
|
|
96
|
+
width: 0.1em;
|
|
97
|
+
height: 0.2em;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.theme__icon-part:nth-child(3) {
|
|
101
|
+
transform: rotate(45deg) translateY(0.45em);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.theme__icon-part:nth-child(4) {
|
|
105
|
+
transform: rotate(90deg) translateY(0.45em);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.theme__icon-part:nth-child(5) {
|
|
109
|
+
transform: rotate(135deg) translateY(0.45em);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.theme__icon-part:nth-child(6) {
|
|
113
|
+
transform: rotate(180deg) translateY(0.45em);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.theme__icon-part:nth-child(7) {
|
|
117
|
+
transform: rotate(225deg) translateY(0.45em);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.theme__icon-part:nth-child(8) {
|
|
121
|
+
transform: rotate(270deg) translateY(0.5em);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.theme__icon-part:nth-child(9) {
|
|
125
|
+
transform: rotate(315deg) translateY(0.5em);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.theme__label,
|
|
129
|
+
.theme__toggle,
|
|
130
|
+
.theme__toggle-wrap {
|
|
131
|
+
position: relative;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.theme__toggle,
|
|
135
|
+
.theme__toggle:before {
|
|
136
|
+
display: block;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
.theme__toggle {
|
|
140
|
+
background-color: hsl(48,90%,85%);
|
|
141
|
+
border-radius: 25% / 50%;
|
|
142
|
+
box-shadow: 0 0 0 0.125em var(--primaryT);
|
|
143
|
+
padding: 0.25em;
|
|
144
|
+
width: 6em;
|
|
145
|
+
height: 3em;
|
|
146
|
+
-webkit-appearance: none;
|
|
147
|
+
appearance: none;
|
|
148
|
+
transition: background-color var(--transDur) ease-in-out,
|
|
149
|
+
box-shadow 0.15s ease-in-out,
|
|
150
|
+
transform var(--transDur) ease-in-out;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.theme__toggle:before {
|
|
154
|
+
background-color: hsl(48,90%,55%);
|
|
155
|
+
border-radius: 50%;
|
|
156
|
+
content: "";
|
|
157
|
+
width: 2.5em;
|
|
158
|
+
height: 2.5em;
|
|
159
|
+
transition: 0.3s;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.theme__toggle:focus {
|
|
163
|
+
box-shadow: 0 0 0 0.125em var(--primary);
|
|
164
|
+
outline: transparent;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* Checked */
|
|
168
|
+
.theme__toggle:checked {
|
|
169
|
+
background-color: hsl(198,90%,15%);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.theme__toggle:checked:before,
|
|
173
|
+
.theme__toggle:checked ~ .theme__icon {
|
|
174
|
+
transform: translateX(3em);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.theme__toggle:checked:before {
|
|
178
|
+
background-color: hsl(198,90%,55%);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.theme__toggle:checked ~ .theme__fill {
|
|
182
|
+
transform: translateX(0);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(1) {
|
|
186
|
+
box-shadow: 0.2em -0.2em 0 0.2em hsl(0,0%,100%) inset;
|
|
187
|
+
transform: scale(1);
|
|
188
|
+
top: 0.2em;
|
|
189
|
+
left: -0.2em;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part ~ .theme__icon-part {
|
|
193
|
+
opacity: 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(2) {
|
|
197
|
+
transform: rotate(45deg) translateY(0.8em);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(3) {
|
|
201
|
+
transform: rotate(90deg) translateY(0.8em);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(4) {
|
|
205
|
+
transform: rotate(135deg) translateY(0.8em);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(5) {
|
|
209
|
+
transform: rotate(180deg) translateY(0.8em);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(6) {
|
|
213
|
+
transform: rotate(225deg) translateY(0.8em);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(7) {
|
|
217
|
+
transform: rotate(270deg) translateY(0.8em);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(8) {
|
|
221
|
+
transform: rotate(315deg) translateY(0.8em);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.theme__toggle:checked ~ .theme__icon .theme__icon-part:nth-child(9) {
|
|
225
|
+
transform: rotate(360deg) translateY(0.8em);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.theme__toggle-wrap {
|
|
229
|
+
margin: 0 0.75em;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
@supports selector(:focus-visible) {
|
|
233
|
+
.theme__toggle:focus {
|
|
234
|
+
box-shadow: 0 0 0 0.125em var(--primaryT);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.theme__toggle:focus-visible {
|
|
238
|
+
box-shadow: 0 0 0 0.125em var(--primary);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
</style>
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Message 全局消息提示服务
|
|
3
|
+
*
|
|
4
|
+
* 使用方法:
|
|
5
|
+
* import { message } from '@/components/message.js'
|
|
6
|
+
*
|
|
7
|
+
* message.success('操作成功')
|
|
8
|
+
* message.error('操作失败')
|
|
9
|
+
* message.warning('警告信息')
|
|
10
|
+
* message.info('提示信息')
|
|
11
|
+
*
|
|
12
|
+
* // 带配置
|
|
13
|
+
* message.success('操作成功', { duration: 5000, closable: true })
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { createApp, h, ref } from 'vue'
|
|
17
|
+
import Message from './Message.vue'
|
|
18
|
+
|
|
19
|
+
let messageInstance = null
|
|
20
|
+
let messageContainer = null
|
|
21
|
+
|
|
22
|
+
// Initialize message instance
|
|
23
|
+
const initMessage = () => {
|
|
24
|
+
if (messageInstance) return messageInstance
|
|
25
|
+
|
|
26
|
+
messageContainer = document.createElement('div')
|
|
27
|
+
messageContainer.id = 'ld-message-container'
|
|
28
|
+
document.body.appendChild(messageContainer)
|
|
29
|
+
|
|
30
|
+
const app = createApp({
|
|
31
|
+
setup () {
|
|
32
|
+
const messageRef = ref(null)
|
|
33
|
+
return () => h(Message, { ref: messageRef })
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const vm = app.mount(messageContainer)
|
|
38
|
+
messageInstance = vm.$el.__vueParentComponent?.exposed || vm.$el.parentNode?.__vueParentComponent?.subTree?.component?.exposed
|
|
39
|
+
|
|
40
|
+
// Wait for next tick to get the exposed methods
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
const container = document.querySelector('#ld-message-container')
|
|
44
|
+
if (container) {
|
|
45
|
+
const vueInstance = container._vnode?.component?.subTree?.component?.exposed
|
|
46
|
+
if (vueInstance) {
|
|
47
|
+
messageInstance = vueInstance
|
|
48
|
+
resolve(messageInstance)
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}, 0)
|
|
52
|
+
})
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Create a simpler implementation using reactive state
|
|
56
|
+
const messages = ref([])
|
|
57
|
+
let messageId = 0
|
|
58
|
+
|
|
59
|
+
const typeClasses = {
|
|
60
|
+
success: 'ld-message--success',
|
|
61
|
+
warning: 'ld-message--warning',
|
|
62
|
+
error: 'ld-message--error',
|
|
63
|
+
info: 'ld-message--info'
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const createMessageElement = (options) => {
|
|
67
|
+
const id = ++messageId
|
|
68
|
+
const type = options.type || 'info'
|
|
69
|
+
const content = options.content || ''
|
|
70
|
+
const duration = options.duration ?? 3000
|
|
71
|
+
const closable = options.closable ?? false
|
|
72
|
+
|
|
73
|
+
// Create message element
|
|
74
|
+
const msgEl = document.createElement('div')
|
|
75
|
+
msgEl.className = `ld-message ld-message--${type}`
|
|
76
|
+
msgEl.setAttribute('data-id', id)
|
|
77
|
+
|
|
78
|
+
// Icon SVGs
|
|
79
|
+
const icons = {
|
|
80
|
+
success: `<svg class="ld-message-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
|
81
|
+
<path d="M20 6L9 17l-5-5" stroke-linecap="round" stroke-linejoin="round"/>
|
|
82
|
+
</svg>`,
|
|
83
|
+
warning: `<svg class="ld-message-icon" viewBox="0 0 24 24" fill="currentColor">
|
|
84
|
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
|
85
|
+
</svg>`,
|
|
86
|
+
error: `<svg class="ld-message-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
|
|
87
|
+
<circle cx="12" cy="12" r="10"/>
|
|
88
|
+
<path d="M15 9l-6 6M9 9l6 6" stroke-linecap="round"/>
|
|
89
|
+
</svg>`,
|
|
90
|
+
info: `<svg class="ld-message-icon" viewBox="0 0 24 24" fill="currentColor">
|
|
91
|
+
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"/>
|
|
92
|
+
</svg>`
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
let html = `${icons[type]}<span class="ld-message-content">${content}</span>`
|
|
96
|
+
|
|
97
|
+
if (closable) {
|
|
98
|
+
html += `<button class="ld-message-close" onclick="window.__ldMessageClose(${id})">
|
|
99
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
100
|
+
<path d="M18 6L6 18M6 6l12 12"/>
|
|
101
|
+
</svg>
|
|
102
|
+
</button>`
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
msgEl.innerHTML = html
|
|
106
|
+
|
|
107
|
+
return { id, element: msgEl, duration }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Ensure container exists
|
|
111
|
+
const ensureContainer = () => {
|
|
112
|
+
let container = document.getElementById('ld-message-root')
|
|
113
|
+
if (!container) {
|
|
114
|
+
container = document.createElement('div')
|
|
115
|
+
container.id = 'ld-message-root'
|
|
116
|
+
document.body.appendChild(container)
|
|
117
|
+
|
|
118
|
+
// Add styles
|
|
119
|
+
const style = document.createElement('style')
|
|
120
|
+
style.textContent = `
|
|
121
|
+
#ld-message-root {
|
|
122
|
+
position: fixed;
|
|
123
|
+
top: 16px;
|
|
124
|
+
left: 50%;
|
|
125
|
+
transform: translateX(-50%);
|
|
126
|
+
z-index: 9999;
|
|
127
|
+
display: flex;
|
|
128
|
+
flex-direction: column;
|
|
129
|
+
align-items: center;
|
|
130
|
+
gap: 12px;
|
|
131
|
+
pointer-events: none;
|
|
132
|
+
}
|
|
133
|
+
.ld-message {
|
|
134
|
+
pointer-events: auto;
|
|
135
|
+
display: flex;
|
|
136
|
+
align-items: center;
|
|
137
|
+
gap: 12px;
|
|
138
|
+
padding: 12px 20px;
|
|
139
|
+
border-radius: 8px;
|
|
140
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
141
|
+
backdrop-filter: blur(8px);
|
|
142
|
+
animation: ldMessageIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
|
143
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
144
|
+
font-size: 14px;
|
|
145
|
+
font-weight: 500;
|
|
146
|
+
}
|
|
147
|
+
.ld-message.ld-message--closing {
|
|
148
|
+
animation: ldMessageOut 0.2s ease-in forwards;
|
|
149
|
+
}
|
|
150
|
+
.ld-message--success { background: rgba(16, 185, 129, 0.95); color: white; }
|
|
151
|
+
.ld-message--warning { background: rgba(245, 158, 11, 0.95); color: white; }
|
|
152
|
+
.ld-message--error { background: rgba(239, 68, 68, 0.95); color: white; }
|
|
153
|
+
.ld-message--info { background: rgba(14, 165, 233, 0.95); color: white; }
|
|
154
|
+
.ld-message-icon { width: 20px; height: 20px; flex-shrink: 0; }
|
|
155
|
+
.ld-message-content { white-space: nowrap; }
|
|
156
|
+
.ld-message-close {
|
|
157
|
+
display: flex;
|
|
158
|
+
align-items: center;
|
|
159
|
+
justify-content: center;
|
|
160
|
+
width: 20px;
|
|
161
|
+
height: 20px;
|
|
162
|
+
margin-left: 4px;
|
|
163
|
+
padding: 0;
|
|
164
|
+
border: none;
|
|
165
|
+
background: transparent;
|
|
166
|
+
color: currentColor;
|
|
167
|
+
cursor: pointer;
|
|
168
|
+
border-radius: 50%;
|
|
169
|
+
transition: background 0.2s;
|
|
170
|
+
}
|
|
171
|
+
.ld-message-close:hover { background: rgba(255,255,255,0.2); }
|
|
172
|
+
.ld-message-close svg { width: 14px; height: 14px; }
|
|
173
|
+
@keyframes ldMessageIn {
|
|
174
|
+
from { opacity: 0; transform: translateY(-20px) scale(0.9); }
|
|
175
|
+
to { opacity: 1; transform: translateY(0) scale(1); }
|
|
176
|
+
}
|
|
177
|
+
@keyframes ldMessageOut {
|
|
178
|
+
from { opacity: 1; transform: translateY(0) scale(1); }
|
|
179
|
+
to { opacity: 0; transform: translateY(-10px) scale(0.95); }
|
|
180
|
+
}
|
|
181
|
+
`
|
|
182
|
+
document.head.appendChild(style)
|
|
183
|
+
}
|
|
184
|
+
return container
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Close message
|
|
188
|
+
const closeMessage = (id) => {
|
|
189
|
+
const container = document.getElementById('ld-message-root')
|
|
190
|
+
if (!container) return
|
|
191
|
+
|
|
192
|
+
const msgEl = container.querySelector(`[data-id="${id}"]`)
|
|
193
|
+
if (msgEl) {
|
|
194
|
+
msgEl.classList.add('ld-message--closing')
|
|
195
|
+
setTimeout(() => {
|
|
196
|
+
msgEl.remove()
|
|
197
|
+
}, 200)
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Expose close function globally
|
|
202
|
+
if (typeof window !== 'undefined') {
|
|
203
|
+
window.__ldMessageClose = closeMessage
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Show message
|
|
207
|
+
const showMessage = (options) => {
|
|
208
|
+
const container = ensureContainer()
|
|
209
|
+
const { id, element, duration } = createMessageElement(options)
|
|
210
|
+
|
|
211
|
+
container.appendChild(element)
|
|
212
|
+
|
|
213
|
+
if (duration > 0) {
|
|
214
|
+
setTimeout(() => {
|
|
215
|
+
closeMessage(id)
|
|
216
|
+
}, duration)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return id
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Export message API
|
|
223
|
+
export const message = {
|
|
224
|
+
success: (content, options = {}) => showMessage({ ...options, type: 'success', content }),
|
|
225
|
+
warning: (content, options = {}) => showMessage({ ...options, type: 'warning', content }),
|
|
226
|
+
error: (content, options = {}) => showMessage({ ...options, type: 'error', content }),
|
|
227
|
+
info: (content, options = {}) => showMessage({ ...options, type: 'info', content }),
|
|
228
|
+
close: closeMessage,
|
|
229
|
+
closeAll: () => {
|
|
230
|
+
const container = document.getElementById('ld-message-root')
|
|
231
|
+
if (container) {
|
|
232
|
+
container.innerHTML = ''
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export default message
|
|
238
|
+
|
package/src/index.js
CHANGED
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
import Button from './components/Button.vue'
|
|
24
24
|
import Card from './components/Card.vue'
|
|
25
25
|
import Modal from './components/Modal.vue'
|
|
26
|
+
import Message from './components/Message.vue'
|
|
27
|
+
import { message } from './components/message.js'
|
|
26
28
|
|
|
27
29
|
// 导入自定义组件(由 Demo 上传生成)
|
|
28
30
|
import { customComponents } from './components/custom/index.js'
|
|
@@ -35,6 +37,7 @@ const components = {
|
|
|
35
37
|
Button,
|
|
36
38
|
Card,
|
|
37
39
|
Modal,
|
|
40
|
+
Message,
|
|
38
41
|
...customComponents
|
|
39
42
|
}
|
|
40
43
|
|
|
@@ -53,7 +56,7 @@ export const registerSnippets = snippetsModule.registerSnippets
|
|
|
53
56
|
export const getSnippet = snippetsModule.getSnippet
|
|
54
57
|
|
|
55
58
|
// 导出内置组件(按需引入)
|
|
56
|
-
export { Button, Card, Modal }
|
|
59
|
+
export { Button, Card, Modal, Message, message }
|
|
57
60
|
|
|
58
61
|
// 重新导出自定义组件
|
|
59
62
|
export * from './components/custom/index.js'
|