@xlui/xux-ui 0.1.0 → 0.2.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/package.json CHANGED
@@ -1,57 +1,60 @@
1
- {
2
- "name": "@xlui/xux-ui",
3
- "version": "0.1.0",
4
- "description": "VUE3 电商组件库",
5
- "author": "leheya",
6
- "license": "MIT",
7
- "main": "./dist/index.js",
8
- "module": "./dist/index.mjs",
9
- "types": "./dist/index.d.ts",
10
- "exports": {
11
- ".": {
12
- "types": "./dist/index.d.ts",
13
- "import": "./dist/index.mjs",
14
- "require": "./dist/index.js"
15
- },
16
- "./*": {
17
- "types": "./dist/*.d.ts",
18
- "import": "./dist/*.mjs",
19
- "require": "./dist/*.js"
20
- }
21
- },
22
- "files": [
23
- "dist",
24
- "src",
25
- "README.md"
26
- ],
27
- "scripts": {
28
- "dev": "vite build --watch",
29
- "build": "vite build",
30
- "prepublishOnly": "pnpm build"
31
- },
32
- "keywords": [
33
- "vue3",
34
- "vue3-ui",
35
- "components",
36
- "ui-library"
37
- ],
38
- "repository": {
39
- "type": "git",
40
- "url": "https://gitee.com/leheya/xux"
41
- },
42
- "homepage": "https://gitee.com/leheya/xux",
43
- "bugs": {
44
- "url": "https://gitee.com/leheya/xux/issues"
45
- },
46
- "peerDependencies": {
47
- "vue": "^3.3.0"
48
- },
49
- "devDependencies": {
50
- "@vitejs/plugin-vue": "^5.0.3",
51
- "typescript": "^5.3.3",
52
- "vite": "^5.0.11",
53
- "vue": "^3.4.15",
54
- "vue-tsc": "^1.8.27"
55
- }
56
- }
57
-
1
+ {
2
+ "name": "@xlui/xux-ui",
3
+ "version": "0.2.0",
4
+ "description": "VUE3 电商组件库",
5
+ "author": "leheya",
6
+ "license": "MIT",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ },
16
+ "./dist/index.css": "./dist/index.css",
17
+ "./style.css": "./dist/index.css",
18
+ "./*": {
19
+ "types": "./dist/*.d.ts",
20
+ "import": "./dist/*.mjs",
21
+ "require": "./dist/*.js"
22
+ }
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "src",
27
+ "README.md"
28
+ ],
29
+ "keywords": [
30
+ "vue3",
31
+ "vue3-ui",
32
+ "components",
33
+ "ui-library",
34
+ "ecommerce",
35
+ "电商组件",
36
+ "ui-components"
37
+ ],
38
+ "repository": {
39
+ "type": "git",
40
+ "url": "https://gitee.com/leheya/xux"
41
+ },
42
+ "homepage": "https://gitee.com/leheya/xux",
43
+ "bugs": {
44
+ "url": "https://gitee.com/leheya/xux/issues"
45
+ },
46
+ "peerDependencies": {
47
+ "vue": "^3.3.0"
48
+ },
49
+ "devDependencies": {
50
+ "@vitejs/plugin-vue": "^5.0.3",
51
+ "typescript": "^5.3.3",
52
+ "vite": "^5.0.11",
53
+ "vue": "^3.4.15",
54
+ "vue-tsc": "^1.8.27"
55
+ },
56
+ "scripts": {
57
+ "dev": "vite build --watch",
58
+ "build": "vite build"
59
+ }
60
+ }
@@ -12,6 +12,7 @@
12
12
  'is-disabled': disabled || item.disabled
13
13
  }"
14
14
  >
15
+
15
16
  <button
16
17
  @click="toggle(index)"
17
18
  class="accordion-header"
@@ -49,6 +50,7 @@
49
50
  </template>
50
51
 
51
52
  <script setup lang="ts">
53
+
52
54
  import { withDefaults, watch, nextTick, ref } from 'vue'
53
55
 
54
56
  /**
@@ -86,9 +86,9 @@ interface Props {
86
86
  */
87
87
  round?: boolean
88
88
  /**
89
- * 是否为朴素按钮
89
+ * 是否为幽灵按钮(透明背景,只有边框)
90
90
  */
91
- plain?: boolean
91
+ ghost?: boolean
92
92
  }
93
93
 
94
94
  const props = withDefaults(defineProps<Props>(), {
@@ -98,7 +98,7 @@ const props = withDefaults(defineProps<Props>(), {
98
98
  loading: false,
99
99
  block: false,
100
100
  round: false,
101
- plain: false
101
+ ghost: false
102
102
  })
103
103
 
104
104
  const emit = defineEmits<{
@@ -131,7 +131,7 @@ const buttonClass = computed(() => {
131
131
  'x-btn-loading': props.loading,
132
132
  'x-btn-block': props.block,
133
133
  'x-btn-round': props.round,
134
- 'x-btn-plain': props.plain,
134
+ 'x-btn-ghost': props.ghost,
135
135
  }
136
136
  ]
137
137
  })
@@ -340,53 +340,100 @@ function handleMouseDown(event: MouseEvent) {
340
340
  color: var(--x-color-primary, #ff6b35);
341
341
  }
342
342
 
343
- /* 朴素按钮 */
344
- .x-btn-plain.x-btn-primary {
345
- background-color: rgba(26, 26, 26, 0.1);
346
- border-color: var(--x-color-primary-lighter, #ffad8d);
347
- color: white;
343
+ /* 幽灵按钮 - Ghost Button */
344
+ .x-btn-ghost.x-btn-default {
345
+ background-color: transparent;
346
+ background: transparent;
347
+ border-color: var(--x-color-gray-300, #cacaca);
348
+ color: var(--x-color-black, #1a1a1a);
349
+ box-shadow: none;
348
350
  }
349
351
 
350
- .x-btn-plain.x-btn-primary:hover:not(.x-btn-disabled):not(.x-btn-loading) {
351
- background-color: rgba(26, 26, 26, 0.2);
352
- border-color: var(--x-color-primary, #1a1a1a);
353
- color: white;
352
+ .x-btn-ghost.x-btn-default:hover:not(.x-btn-disabled):not(.x-btn-loading) {
353
+ background-color: rgba(26, 26, 26, 0.05);
354
+ background: rgba(26, 26, 26, 0.05);
355
+ border-color: var(--x-color-gray-400, #a0a0a0);
354
356
  }
355
357
 
356
- .x-btn-plain.x-btn-success {
357
- background-color: rgba(16, 185, 129, 0.1);
358
- border-color: var(--x-color-success-lighter, #6ee7b7);
359
- color: white;
358
+ .x-btn-ghost.x-btn-primary {
359
+ background-color: transparent;
360
+ background: transparent;
361
+ border-color: var(--x-color-primary, #ff6b35);
362
+ color: var(--x-color-primary, #ff6b35);
363
+ box-shadow: none;
360
364
  }
361
365
 
362
- .x-btn-plain.x-btn-success:hover:not(.x-btn-disabled):not(.x-btn-loading) {
363
- background-color: rgba(16, 185, 129, 0.2);
366
+ .x-btn-ghost.x-btn-primary:hover:not(.x-btn-disabled):not(.x-btn-loading) {
367
+ background-color: rgba(255, 107, 53, 0.1);
368
+ background: rgba(255, 107, 53, 0.1);
369
+ border-color: var(--x-color-primary, #ff6b35);
370
+ box-shadow: none;
371
+ }
372
+
373
+ .x-btn-ghost.x-btn-success {
374
+ background-color: transparent;
375
+ background: transparent;
364
376
  border-color: var(--x-color-success, #10b981);
365
- color: white;
377
+ color: var(--x-color-success, #10b981);
378
+ box-shadow: none;
366
379
  }
367
380
 
368
- .x-btn-plain.x-btn-warning {
369
- background-color: rgba(245, 158, 11, 0.1);
370
- border-color: var(--x-color-warning-lighter, #fcd34d);
371
- color: white;
381
+ .x-btn-ghost.x-btn-success:hover:not(.x-btn-disabled):not(.x-btn-loading) {
382
+ background-color: rgba(16, 185, 129, 0.1);
383
+ background: rgba(16, 185, 129, 0.1);
384
+ border-color: var(--x-color-success, #10b981);
385
+ box-shadow: none;
372
386
  }
373
387
 
374
- .x-btn-plain.x-btn-warning:hover:not(.x-btn-disabled):not(.x-btn-loading) {
375
- background-color: rgba(245, 158, 11, 0.2);
388
+ .x-btn-ghost.x-btn-warning {
389
+ background-color: transparent;
390
+ background: transparent;
376
391
  border-color: var(--x-color-warning, #f59e0b);
377
- color: white;
392
+ color: var(--x-color-warning, #f59e0b);
393
+ box-shadow: none;
378
394
  }
379
395
 
380
- .x-btn-plain.x-btn-danger {
381
- background-color: rgba(239, 68, 68, 0.1);
382
- border-color: var(--x-color-danger-lighter, #fca5a5);
383
- color: white;
396
+ .x-btn-ghost.x-btn-warning:hover:not(.x-btn-disabled):not(.x-btn-loading) {
397
+ background-color: rgba(245, 158, 11, 0.1);
398
+ background: rgba(245, 158, 11, 0.1);
399
+ border-color: var(--x-color-warning, #f59e0b);
400
+ box-shadow: none;
384
401
  }
385
402
 
386
- .x-btn-plain.x-btn-danger:hover:not(.x-btn-disabled):not(.x-btn-loading) {
387
- background-color: rgba(239, 68, 68, 0.2);
403
+ .x-btn-ghost.x-btn-danger {
404
+ background-color: transparent;
405
+ background: transparent;
388
406
  border-color: var(--x-color-danger, #ef4444);
389
- color: white;
407
+ color: var(--x-color-danger, #ef4444);
408
+ box-shadow: none;
409
+ }
410
+
411
+ .x-btn-ghost.x-btn-danger:hover:not(.x-btn-disabled):not(.x-btn-loading) {
412
+ background-color: rgba(239, 68, 68, 0.1);
413
+ background: rgba(239, 68, 68, 0.1);
414
+ border-color: var(--x-color-danger, #ef4444);
415
+ box-shadow: none;
416
+ }
417
+
418
+ /* 幽灵按钮波纹效果调整 */
419
+ .x-btn-ghost .x-btn-ripple {
420
+ background-color: rgba(0, 0, 0, 0.08);
421
+ }
422
+
423
+ .x-btn-ghost.x-btn-primary .x-btn-ripple {
424
+ background-color: rgba(255, 107, 53, 0.15);
425
+ }
426
+
427
+ .x-btn-ghost.x-btn-success .x-btn-ripple {
428
+ background-color: rgba(16, 185, 129, 0.15);
429
+ }
430
+
431
+ .x-btn-ghost.x-btn-warning .x-btn-ripple {
432
+ background-color: rgba(245, 158, 11, 0.15);
433
+ }
434
+
435
+ .x-btn-ghost.x-btn-danger .x-btn-ripple {
436
+ background-color: rgba(239, 68, 68, 0.15);
390
437
  }
391
438
 
392
439
  /* 圆角按钮 */
@@ -0,0 +1,374 @@
1
+ <template>
2
+ <div
3
+ :class="[
4
+ variant === 'basic' ? 'x-tooltip-wrapper' : 'x-tooltip-rich-wrapper',
5
+ variant === 'rich' && `rich-${placement}`
6
+ ]"
7
+ >
8
+ <!-- 基本版本 -->
9
+ <template v-if="variant === 'basic'">
10
+ <div class="x-tooltip-trigger">
11
+ <slot></slot>
12
+ </div>
13
+ <div :class="['x-tooltip', `tooltip-${placement}`]">
14
+ {{ content }}
15
+ <div :class="['tooltip-arrow', `arrow-${placement}`]"></div>
16
+ </div>
17
+ </template>
18
+
19
+ <!-- 丰富版本 (基于 CSS Buttons) -->
20
+ <template v-else>
21
+ <span class="tooltip-label">{{ label }}</span>
22
+ <span class="tooltip-text">{{ content }}</span>
23
+ <span class="tooltip-hover-text">{{ hoverText || label }}</span>
24
+ </template>
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ export interface TooltipsProps {
30
+ /** Tooltip 显示的内容 */
31
+ content: string
32
+ /** Tooltip 显示的位置: 'top' | 'bottom' | 'left' | 'right' */
33
+ placement?: 'top' | 'bottom' | 'left' | 'right'
34
+ /** 变体类型: 'basic' | 'rich' */
35
+ variant?: 'basic' | 'rich'
36
+ /** 丰富版本的标签文字 */
37
+ label?: string
38
+ /** 丰富版本的悬停文字 */
39
+ hoverText?: string
40
+ }
41
+
42
+ withDefaults(defineProps<TooltipsProps>(), {
43
+ placement: 'top',
44
+ variant: 'basic',
45
+ label: 'Hover',
46
+ hoverText: ''
47
+ })
48
+ </script>
49
+
50
+ <style scoped>
51
+ /* ===== 基本版本样式 ===== */
52
+ .x-tooltip-wrapper {
53
+ position: relative;
54
+ display: inline-block;
55
+ }
56
+
57
+ .x-tooltip-trigger {
58
+ cursor: pointer;
59
+ }
60
+
61
+ .x-tooltip {
62
+ position: absolute;
63
+ background-color: #1a1a1a;
64
+ color: #ffffff;
65
+ padding: 8px 12px;
66
+ border-radius: 6px;
67
+ font-size: 14px;
68
+ white-space: nowrap;
69
+ opacity: 0;
70
+ visibility: hidden;
71
+ transition: opacity 0.3s ease, visibility 0.3s ease, transform 0.3s ease;
72
+ z-index: 1000;
73
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
74
+ pointer-events: none;
75
+ }
76
+
77
+ .tooltip-arrow {
78
+ position: absolute;
79
+ width: 8px;
80
+ height: 8px;
81
+ background-color: #1a1a1a;
82
+ transform: rotate(45deg);
83
+ }
84
+
85
+ /* 上方 */
86
+ .tooltip-top {
87
+ bottom: 100%;
88
+ left: 50%;
89
+ transform: translate(-50%, -8px);
90
+ margin-bottom: 8px;
91
+ }
92
+
93
+ .arrow-top {
94
+ bottom: -4px;
95
+ left: 50%;
96
+ margin-left: -4px;
97
+ }
98
+
99
+ .x-tooltip-wrapper:hover .tooltip-top {
100
+ opacity: 1;
101
+ visibility: visible;
102
+ transform: translate(-50%, 0);
103
+ }
104
+
105
+ /* 下方 */
106
+ .tooltip-bottom {
107
+ top: 100%;
108
+ left: 50%;
109
+ transform: translate(-50%, 8px);
110
+ margin-top: 8px;
111
+ }
112
+
113
+ .arrow-bottom {
114
+ top: -4px;
115
+ left: 50%;
116
+ margin-left: -4px;
117
+ }
118
+
119
+ .x-tooltip-wrapper:hover .tooltip-bottom {
120
+ opacity: 1;
121
+ visibility: visible;
122
+ transform: translate(-50%, 0);
123
+ }
124
+
125
+ /* 左侧 */
126
+ .tooltip-left {
127
+ right: 100%;
128
+ top: 50%;
129
+ transform: translate(-8px, -50%);
130
+ margin-right: 8px;
131
+ }
132
+
133
+ .arrow-left {
134
+ right: -4px;
135
+ top: 50%;
136
+ margin-top: -4px;
137
+ }
138
+
139
+ .x-tooltip-wrapper:hover .tooltip-left {
140
+ opacity: 1;
141
+ visibility: visible;
142
+ transform: translate(0, -50%);
143
+ }
144
+
145
+ /* 右侧 */
146
+ .tooltip-right {
147
+ left: 100%;
148
+ top: 50%;
149
+ transform: translate(8px, -50%);
150
+ margin-left: 8px;
151
+ }
152
+
153
+ .arrow-right {
154
+ left: -4px;
155
+ top: 50%;
156
+ margin-top: -4px;
157
+ }
158
+
159
+ .x-tooltip-wrapper:hover .tooltip-right {
160
+ opacity: 1;
161
+ visibility: visible;
162
+ transform: translate(0, -50%);
163
+ }
164
+
165
+ /* ===== 丰富版本样式 (基于 CSS Buttons) ===== */
166
+ .x-tooltip-rich-wrapper {
167
+ --background: #1a1a1a;
168
+ --color: #ffffff;
169
+ --border-color: #333333;
170
+ position: relative;
171
+ cursor: pointer;
172
+ transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
173
+ font-size: 18px;
174
+ font-weight: 600;
175
+ color: #333333;
176
+ background-color: #ffffff;
177
+ padding: 0.7em 1.8em;
178
+ border-radius: 8px;
179
+ text-transform: uppercase;
180
+ height: 60px;
181
+ width: 180px;
182
+ display: grid;
183
+ place-items: center;
184
+ border: 2px solid var(--border-color);
185
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
186
+ }
187
+
188
+ .tooltip-text {
189
+ position: absolute;
190
+ top: 0;
191
+ left: 0;
192
+ width: 100%;
193
+ height: 100%;
194
+ display: grid;
195
+ place-items: center;
196
+ transform-origin: -100%;
197
+ transform: scale(1);
198
+ transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
199
+ z-index: 2;
200
+ color: #333333;
201
+ }
202
+
203
+ .x-tooltip-rich-wrapper .tooltip-hover-text {
204
+ position: absolute;
205
+ top: 0%;
206
+ left: 100%;
207
+ width: 100%;
208
+ height: 100%;
209
+ border-radius: 8px;
210
+ opacity: 1;
211
+ background-color: var(--background);
212
+ color: var(--color);
213
+ z-index: 1;
214
+ border: 2px solid var(--background);
215
+ transform: scale(0);
216
+ transform-origin: 0;
217
+ transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
218
+ display: grid;
219
+ place-items: center;
220
+ }
221
+
222
+ .tooltip-label {
223
+ position: absolute;
224
+ padding: 0.3em 0.6em;
225
+ opacity: 0;
226
+ pointer-events: none;
227
+ transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);
228
+ background: var(--background);
229
+ z-index: 10;
230
+ border-radius: 8px;
231
+ scale: 0;
232
+ text-transform: capitalize;
233
+ font-weight: 400;
234
+ font-size: 16px;
235
+ box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px;
236
+ }
237
+
238
+ .tooltip-label::before {
239
+ position: absolute;
240
+ content: "";
241
+ height: 0.6em;
242
+ width: 0.6em;
243
+ background: var(--background);
244
+ }
245
+
246
+ /* 丰富版本 - 上方 */
247
+ .rich-top .tooltip-label {
248
+ top: -0.5em;
249
+ left: 50%;
250
+ transform: translateX(-50%);
251
+ transform-origin: 0 0;
252
+ }
253
+
254
+ .rich-top .tooltip-label::before {
255
+ bottom: -0.2em;
256
+ left: 50%;
257
+ transform: translate(-50%) rotate(45deg);
258
+ }
259
+
260
+ .rich-top:hover .tooltip-label {
261
+ top: calc(-100% - 1em);
262
+ opacity: 1;
263
+ visibility: visible;
264
+ pointer-events: auto;
265
+ scale: 1;
266
+ animation: shake 0.5s ease-in-out both;
267
+ }
268
+
269
+ /* 丰富版本 - 下方 */
270
+ .rich-bottom .tooltip-label {
271
+ bottom: -0.5em;
272
+ left: 50%;
273
+ transform: translateX(-50%);
274
+ transform-origin: 50% 100%;
275
+ }
276
+
277
+ .rich-bottom .tooltip-label::before {
278
+ top: -0.2em;
279
+ left: 50%;
280
+ transform: translate(-50%) rotate(45deg);
281
+ }
282
+
283
+ .rich-bottom:hover .tooltip-label {
284
+ bottom: calc(-100% - 1em);
285
+ opacity: 1;
286
+ visibility: visible;
287
+ pointer-events: auto;
288
+ scale: 1;
289
+ animation: shake 0.5s ease-in-out both;
290
+ }
291
+
292
+ /* 丰富版本 - 左侧 */
293
+ .rich-left .tooltip-label {
294
+ top: 50%;
295
+ right: calc(100% + 0.5em);
296
+ transform: translateY(-50%);
297
+ transform-origin: 100% 50%;
298
+ }
299
+
300
+ .rich-left .tooltip-label::before {
301
+ right: -0.2em;
302
+ top: 50%;
303
+ transform: translateY(-50%) rotate(45deg);
304
+ }
305
+
306
+ .rich-left:hover .tooltip-label {
307
+ right: calc(100% + 1em);
308
+ opacity: 1;
309
+ visibility: visible;
310
+ pointer-events: auto;
311
+ scale: 1;
312
+ animation: shake 0.5s ease-in-out both;
313
+ }
314
+
315
+ /* 丰富版本 - 右侧 */
316
+ .rich-right .tooltip-label {
317
+ top: 50%;
318
+ left: calc(100% + 0.5em);
319
+ transform: translateY(-50%);
320
+ transform-origin: 0 50%;
321
+ }
322
+
323
+ .rich-right .tooltip-label::before {
324
+ left: -0.2em;
325
+ top: 50%;
326
+ transform: translateY(-50%) rotate(45deg);
327
+ }
328
+
329
+ .rich-right:hover .tooltip-label {
330
+ left: calc(100% + 1em);
331
+ opacity: 1;
332
+ visibility: visible;
333
+ pointer-events: auto;
334
+ scale: 1;
335
+ animation: shake 0.5s ease-in-out both;
336
+ }
337
+
338
+ /* 丰富版本 - 悬停效果 */
339
+ .x-tooltip-rich-wrapper:hover {
340
+ box-shadow: rgba(0, 0, 0, 0.25) 0 8px 15px;
341
+ color: white;
342
+ border-color: transparent;
343
+ }
344
+
345
+ .x-tooltip-rich-wrapper:hover .tooltip-hover-text {
346
+ transform: scale(1);
347
+ left: 0;
348
+ }
349
+
350
+ .x-tooltip-rich-wrapper:hover .tooltip-text {
351
+ opacity: 0;
352
+ top: 0%;
353
+ left: 100%;
354
+ transform: scale(0);
355
+ }
356
+
357
+ @keyframes shake {
358
+ 0% {
359
+ rotate: 0;
360
+ }
361
+ 25% {
362
+ rotate: 7deg;
363
+ }
364
+ 50% {
365
+ rotate: -7deg;
366
+ }
367
+ 75% {
368
+ rotate: 1deg;
369
+ }
370
+ 100% {
371
+ rotate: 0;
372
+ }
373
+ }
374
+ </style>