@bagelink/vue 0.0.827 → 0.0.833
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/components/Carousel.vue.d.ts +27 -4
- package/dist/components/Carousel.vue.d.ts.map +1 -1
- package/dist/components/Pill.vue.d.ts +6 -6
- package/dist/components/Pill.vue.d.ts.map +1 -1
- package/dist/index.cjs +108 -144
- package/dist/index.mjs +108 -144
- package/dist/style.css +28 -28
- package/package.json +3 -3
- package/src/components/Carousel.vue +105 -142
- package/src/components/Pill.vue +4 -4
|
@@ -2,221 +2,184 @@
|
|
|
2
2
|
import { onMounted, onUnmounted, watch } from 'vue'
|
|
3
3
|
|
|
4
4
|
const props = defineProps({
|
|
5
|
-
autoHeight: {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
},
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
},
|
|
13
|
-
freeDrag: {
|
|
14
|
-
type: Boolean,
|
|
15
|
-
default: true,
|
|
16
|
-
},
|
|
17
|
-
items: {
|
|
18
|
-
type: Number,
|
|
19
|
-
default: 4,
|
|
20
|
-
},
|
|
21
|
-
index: {
|
|
22
|
-
type: Number,
|
|
23
|
-
default: 0,
|
|
24
|
-
},
|
|
5
|
+
autoHeight: { type: Boolean, default: false },
|
|
6
|
+
allowScroll: { type: Boolean, default: true },
|
|
7
|
+
freeDrag: { type: Boolean, default: true },
|
|
8
|
+
items: { type: Number, default: 4 },
|
|
9
|
+
index: { type: Number, default: 0 },
|
|
10
|
+
rtl: { type: Boolean, default: false },
|
|
11
|
+
autoplay: { type: Boolean, default: false },
|
|
12
|
+
autoPlaySpeed: { type: Number, default: 4000 },
|
|
25
13
|
})
|
|
14
|
+
|
|
26
15
|
const emit = defineEmits(['update:index'])
|
|
27
16
|
const bglSlider = $ref<HTMLElement>()
|
|
17
|
+
|
|
28
18
|
let itemCount = $ref(props.items)
|
|
29
|
-
let activeSlideIndex = $ref(
|
|
19
|
+
let activeSlideIndex = $ref(props.index)
|
|
30
20
|
let isDragging = $ref(false)
|
|
31
|
-
let startX = $ref(0)
|
|
32
|
-
let scrollLeft = $ref(0)
|
|
33
21
|
let isPressed = $ref(false)
|
|
22
|
+
let startX = $ref(0)
|
|
23
|
+
let scrollStart = $ref(0)
|
|
24
|
+
let yHeight = $ref('auto')
|
|
25
|
+
let timeout: NodeJS.Timeout
|
|
26
|
+
let autoPlayInterval: NodeJS.Timeout
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
28
|
+
// Helper Functions
|
|
29
|
+
function preventDefaultClick(e: MouseEvent) {
|
|
30
|
+
e.preventDefault()
|
|
31
|
+
}
|
|
39
32
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
33
|
+
function disableDrag() {
|
|
34
|
+
bglSlider?.querySelectorAll('img').forEach((img) => { img.setAttribute('draggable', 'false') })
|
|
35
|
+
Array.from(bglSlider?.children || []).forEach((child) => {
|
|
36
|
+
child.setAttribute('draggable', 'false');
|
|
37
|
+
(child as HTMLElement).addEventListener('click', preventDefaultClick)
|
|
38
|
+
})
|
|
44
39
|
}
|
|
45
40
|
|
|
46
|
-
|
|
47
|
-
function evalHeight() {
|
|
41
|
+
function updateHeight() {
|
|
48
42
|
if (!props.autoHeight || !bglSlider) return
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
.reduce((a, b) => a + b, 0)
|
|
53
|
-
|
|
54
|
-
yHeight = `${height}px`
|
|
43
|
+
const children = Array.from(bglSlider.children[activeSlideIndex].children)
|
|
44
|
+
const totalHeight = children.reduce((sum, el) => sum + el.clientHeight, 0)
|
|
45
|
+
yHeight = `${totalHeight}px`
|
|
55
46
|
}
|
|
56
47
|
|
|
57
|
-
function
|
|
58
|
-
if (!bglSlider) return
|
|
59
|
-
if (isPressed) return
|
|
48
|
+
function easeScroll(target: number, duration = 500) {
|
|
49
|
+
if (!bglSlider || isPressed) return
|
|
60
50
|
const start = bglSlider.scrollLeft
|
|
61
51
|
const change = target - start
|
|
62
52
|
const startTime = performance.now()
|
|
63
53
|
|
|
64
|
-
function
|
|
54
|
+
function animate(currentTime: number) {
|
|
65
55
|
if (!bglSlider) return
|
|
66
56
|
const timeElapsed = currentTime - startTime
|
|
67
57
|
const progress = Math.min(timeElapsed / duration, 1)
|
|
68
58
|
bglSlider.scrollLeft = start + change * easeInOutQuad(progress)
|
|
69
|
-
if (progress < 1)
|
|
70
|
-
requestAnimationFrame(animateScroll)
|
|
71
|
-
}
|
|
59
|
+
if (progress < 1) requestAnimationFrame(animate)
|
|
72
60
|
}
|
|
73
61
|
|
|
74
62
|
function easeInOutQuad(t: number) {
|
|
75
63
|
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t
|
|
76
64
|
}
|
|
77
65
|
|
|
78
|
-
requestAnimationFrame(
|
|
66
|
+
requestAnimationFrame(animate)
|
|
79
67
|
}
|
|
80
68
|
|
|
81
69
|
function goToSlide(index: number) {
|
|
82
|
-
if (!bglSlider || index < 0 || index
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
let duration = 700
|
|
87
|
-
|
|
88
|
-
if (screenWidth < 600) {
|
|
89
|
-
duration = 400
|
|
90
|
-
} else if (screenWidth < 991) {
|
|
91
|
-
duration = 500
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
scrollEase(scrollX, duration)
|
|
70
|
+
if (!bglSlider || index < 0 || index >= bglSlider.children.length) return
|
|
71
|
+
const offset = bglSlider.offsetWidth * index * (props.rtl ? -1 : 1)
|
|
72
|
+
const duration = window.innerWidth < 600 ? 400 : window.innerWidth < 991 ? 500 : 700
|
|
73
|
+
easeScroll(offset, duration)
|
|
95
74
|
activeSlideIndex = index
|
|
96
|
-
|
|
75
|
+
updateHeight()
|
|
97
76
|
}
|
|
98
77
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
() => activeSlideIndex,
|
|
103
|
-
() => {
|
|
104
|
-
if (props.index === activeSlideIndex) return
|
|
105
|
-
emit('update:index', activeSlideIndex) }
|
|
106
|
-
)
|
|
78
|
+
function handleSlideChange() {
|
|
79
|
+
if (props.index !== activeSlideIndex) emit('update:index', activeSlideIndex)
|
|
80
|
+
}
|
|
107
81
|
|
|
108
|
-
function
|
|
82
|
+
function handleResize() {
|
|
109
83
|
if (!bglSlider) return
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (isDragForward) activeSlideIndex = Math.ceil(bglSlider.scrollLeft / bglSlider.offsetWidth)
|
|
113
|
-
else activeSlideIndex = Math.floor(bglSlider.scrollLeft / bglSlider.offsetWidth)
|
|
114
|
-
} else {
|
|
115
|
-
activeSlideIndex = Math.round(bglSlider.scrollLeft / bglSlider.offsetWidth)
|
|
116
|
-
}
|
|
117
|
-
startX = 0
|
|
118
|
-
const nextSlide = Math.round(bglSlider.scrollLeft / bglSlider.offsetWidth)
|
|
119
|
-
goToSlide(nextSlide)
|
|
84
|
+
itemCount = window.innerWidth < 600 ? 1 : window.innerWidth < 991 ? Math.min(props.items, 2) : Math.min(props.items, 3)
|
|
85
|
+
goToSlide(activeSlideIndex)
|
|
120
86
|
}
|
|
121
87
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
88
|
+
function onScrollEnd() {
|
|
89
|
+
if ((!props.freeDrag && !props.allowScroll) || !bglSlider) return
|
|
90
|
+
if (autoPlayInterval) clearInterval(autoPlayInterval)
|
|
125
91
|
if (timeout) clearTimeout(timeout)
|
|
126
|
-
timeout = setTimeout(
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function stopDragging(e: MouseEvent) {
|
|
130
|
-
isPressed = false
|
|
131
|
-
document.removeEventListener('mousemove', move)
|
|
132
|
-
document.removeEventListener('mouseup', stopDragging)
|
|
133
|
-
document.removeEventListener('dragend', stopDragging)
|
|
134
|
-
setTimeout(() => (isDragging = false), 100)
|
|
92
|
+
timeout = setTimeout(() => { finalizeScroll() }, 400)
|
|
135
93
|
}
|
|
136
94
|
|
|
137
|
-
function
|
|
95
|
+
function finalizeScroll() {
|
|
138
96
|
if (!bglSlider) return
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
const scroll = x - startX
|
|
144
|
-
bglSlider.scrollLeft = scrollLeft - scroll
|
|
97
|
+
if (props.autoplay) autoPlayInterval = setInterval(next, props.autoPlaySpeed)
|
|
98
|
+
scrollStart = props.rtl ? -bglSlider.scrollLeft : bglSlider.scrollLeft
|
|
99
|
+
activeSlideIndex = Math.round(scrollStart / bglSlider.offsetWidth)
|
|
100
|
+
goToSlide(activeSlideIndex)
|
|
145
101
|
}
|
|
146
102
|
|
|
147
|
-
function
|
|
103
|
+
function startDrag(e: MouseEvent) {
|
|
148
104
|
if (e.button !== 0 || !props.freeDrag || !bglSlider) return
|
|
105
|
+
if (autoPlayInterval) clearInterval(autoPlayInterval)
|
|
149
106
|
startX = e.pageX - bglSlider.offsetLeft
|
|
150
|
-
|
|
107
|
+
scrollStart = bglSlider.scrollLeft
|
|
151
108
|
isPressed = true
|
|
152
|
-
document.addEventListener('mousemove',
|
|
153
|
-
document.addEventListener('mouseup',
|
|
154
|
-
// document.addEventListener('dragend', stopDragging)
|
|
109
|
+
document.addEventListener('mousemove', onDrag)
|
|
110
|
+
document.addEventListener('mouseup', endDrag)
|
|
155
111
|
}
|
|
156
112
|
|
|
157
|
-
function
|
|
113
|
+
function onDrag(e: MouseEvent) {
|
|
158
114
|
if (!bglSlider) return
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
if (
|
|
162
|
-
|
|
115
|
+
const x = e.pageX - bglSlider.offsetLeft
|
|
116
|
+
const distance = x - startX
|
|
117
|
+
if (Math.abs(distance) > 20) isDragging = true
|
|
118
|
+
if (isDragging) bglSlider.scrollLeft = scrollStart - distance
|
|
163
119
|
}
|
|
164
120
|
|
|
165
|
-
function
|
|
121
|
+
function endDrag() {
|
|
122
|
+
isPressed = false
|
|
123
|
+
document.removeEventListener('mousemove', onDrag)
|
|
124
|
+
document.removeEventListener('mouseup', endDrag)
|
|
125
|
+
setTimeout(() => (isDragging = false), 100)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Navigation Functions
|
|
129
|
+
function next() {
|
|
166
130
|
if (!bglSlider) return
|
|
167
131
|
const slideCount = bglSlider.children.length
|
|
168
|
-
|
|
169
|
-
else goToSlide(activeSlideIndex - 1)
|
|
132
|
+
goToSlide((activeSlideIndex + 1) % slideCount)
|
|
170
133
|
}
|
|
171
134
|
|
|
172
|
-
function
|
|
135
|
+
function prev() {
|
|
173
136
|
if (!bglSlider) return
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
else if (window.innerWidth < 1280) itemCount = Math.min(props.items, 3)
|
|
177
|
-
else itemCount = props.items
|
|
178
|
-
console.log(itemCount, window.innerWidth)
|
|
179
|
-
goToSlide(activeSlideIndex)
|
|
137
|
+
const slideCount = bglSlider.children.length
|
|
138
|
+
goToSlide((activeSlideIndex - 1 + slideCount) % slideCount)
|
|
180
139
|
}
|
|
181
140
|
|
|
141
|
+
// Lifecycle Hooks
|
|
182
142
|
onMounted(() => {
|
|
183
|
-
window.addEventListener('resize',
|
|
184
|
-
evalHeight()
|
|
185
|
-
evalWidth()
|
|
143
|
+
window.addEventListener('resize', handleResize)
|
|
186
144
|
disableDrag()
|
|
145
|
+
updateHeight()
|
|
146
|
+
handleResize()
|
|
147
|
+
if (props.autoplay) {
|
|
148
|
+
autoPlayInterval = setInterval(next, props.autoPlaySpeed)
|
|
149
|
+
}
|
|
187
150
|
})
|
|
188
151
|
|
|
189
|
-
|
|
152
|
+
function clearAutoplay() {
|
|
153
|
+
if (autoPlayInterval) clearInterval(autoPlayInterval)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
onUnmounted(() => {
|
|
157
|
+
window.removeEventListener('resize', handleResize)
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// Watchers
|
|
161
|
+
watch(() => props.index, goToSlide)
|
|
162
|
+
watch(() => activeSlideIndex, handleSlideChange)
|
|
190
163
|
</script>
|
|
191
164
|
|
|
192
165
|
<template>
|
|
193
|
-
<div class="BglCarousel" :style="{ height: yHeight }" :class="{ autoHeight }">
|
|
166
|
+
<div class="BglCarousel" :style="{ height: yHeight }" :class="{ autoHeight }" :dir="rtl ? 'rtl' : 'ltr'">
|
|
194
167
|
<div
|
|
195
168
|
ref="bglSlider"
|
|
196
|
-
:class="{
|
|
197
|
-
dragging: isDragging,
|
|
198
|
-
clicking: isPressed,
|
|
199
|
-
allowScroll,
|
|
200
|
-
odd: itemCount % 2 !== 0,
|
|
201
|
-
[`slides-${itemCount}`]: itemCount === 1,
|
|
202
|
-
}"
|
|
203
169
|
class="bgl-slider"
|
|
204
|
-
:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
@
|
|
208
|
-
@
|
|
170
|
+
:class="{ dragging: isDragging, clicking: isPressed, allowScroll, odd: itemCount % 2 !== 0, [`slides-${itemCount}`]: itemCount === 1 }"
|
|
171
|
+
:style="{ '--item-count': itemCount }"
|
|
172
|
+
@scroll="onScrollEnd"
|
|
173
|
+
@mousedown="startDrag"
|
|
174
|
+
@mouseover="clearAutoplay"
|
|
175
|
+
@focusin="clearAutoplay"
|
|
209
176
|
>
|
|
210
177
|
<div v-if="isDragging" class="blocker" />
|
|
211
178
|
<slot />
|
|
212
179
|
</div>
|
|
213
180
|
<div class="Handlers">
|
|
214
|
-
<span @click="prev">
|
|
215
|
-
|
|
216
|
-
</span>
|
|
217
|
-
<span @click="next">
|
|
218
|
-
<slot :next :index="activeSlideIndex" name="next" />
|
|
219
|
-
</span>
|
|
181
|
+
<span @click="prev"><slot name="prev" :index="activeSlideIndex" /></span>
|
|
182
|
+
<span @click="next"><slot name="next" :index="activeSlideIndex" /></span>
|
|
220
183
|
</div>
|
|
221
184
|
</div>
|
|
222
185
|
</template>
|
package/src/components/Pill.vue
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import type { MaterialIcons, ThemeType } from '@bagelink/vue'
|
|
2
3
|
import { Btn, MaterialIcon } from '@bagelink/vue'
|
|
3
4
|
import { useSlots } from 'vue'
|
|
4
|
-
import type { MaterialIcons, ThemeType } from '@bagelink/vue'
|
|
5
5
|
|
|
6
6
|
interface BtnProp {
|
|
7
7
|
icon: MaterialIcons
|
|
@@ -12,7 +12,7 @@ interface BtnProp {
|
|
|
12
12
|
const props = defineProps<{
|
|
13
13
|
disabled?: boolean
|
|
14
14
|
icon?: MaterialIcons
|
|
15
|
-
iconEnd
|
|
15
|
+
iconEnd?: MaterialIcons
|
|
16
16
|
color?: ThemeType
|
|
17
17
|
theme?: ThemeType
|
|
18
18
|
flat?: boolean
|
|
@@ -21,8 +21,8 @@ const props = defineProps<{
|
|
|
21
21
|
loading?: boolean
|
|
22
22
|
value?: string
|
|
23
23
|
round?: boolean
|
|
24
|
-
btn
|
|
25
|
-
btnEnd
|
|
24
|
+
btn?: BtnProp
|
|
25
|
+
btnEnd?: BtnProp
|
|
26
26
|
}>()
|
|
27
27
|
|
|
28
28
|
const slots = useSlots()
|