renusify 3.0.0 → 3.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/components/avatar/index.vue +1 -2
- package/components/button/index.vue +4 -4
- package/components/confirm/index.vue +3 -3
- package/components/form/checkboxInput/index.vue +6 -2
- package/components/form/fileInput/index.vue +1 -1
- package/components/form/fileInput/single.vue +47 -42
- package/components/form/telInput/index.vue +1 -1
- package/components/img/index.vue +3 -2
- package/components/infinite/index.js +2 -1
- package/components/infinite/index.vue +81 -39
- package/components/menu/index.vue +5 -3
- package/components/slider/index.vue +2 -1
- package/components/swiper/index.vue +32 -51
- package/directive/scroll/index.js +29 -25
- package/index.js +4 -14
- package/package.json +1 -1
- package/style/variables/base.scss +7 -9
- package/tools/icons.js +1 -1
|
@@ -270,9 +270,9 @@ $btn-sizes: (
|
|
|
270
270
|
'xs': 1.5rem, // 24px - 6 units
|
|
271
271
|
'sm': 2rem, // 32px - 8 units
|
|
272
272
|
'md': 2.5rem, // 40px - 10 units
|
|
273
|
-
'lg':
|
|
274
|
-
'xl': 3.
|
|
275
|
-
'xxl':
|
|
273
|
+
'lg': 3rem, // 48px - 12 units
|
|
274
|
+
'xl': 3.5rem, // 56px - 14 units
|
|
275
|
+
'xxl': 4rem, // 64px - 16 units
|
|
276
276
|
) !default;
|
|
277
277
|
|
|
278
278
|
$btn-font-sizes: (
|
|
@@ -313,7 +313,7 @@ $fab-icon-sizes: (
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
height: $height;
|
|
316
|
-
padding: 0 math.div($height,
|
|
316
|
+
padding: 0 math.div($height, 3);
|
|
317
317
|
font-size: $font-size;
|
|
318
318
|
border-radius: math.div($height, 10);
|
|
319
319
|
}
|
|
@@ -20,16 +20,16 @@
|
|
|
20
20
|
</r-col>
|
|
21
21
|
</r-row>
|
|
22
22
|
<r-row class="h-end no-gutters">
|
|
23
|
-
<r-btn :loading="
|
|
23
|
+
<r-btn :loading="loading"
|
|
24
24
|
@click.stop="cancel"
|
|
25
25
|
class="color-error-text mx-1"
|
|
26
26
|
outlined
|
|
27
27
|
rounded
|
|
28
|
-
v-if="!
|
|
28
|
+
v-if="!loading">
|
|
29
29
|
{{ cancelText || $t('cancel', 'renusify') }}
|
|
30
30
|
</r-btn>
|
|
31
31
|
<r-btn :disabled="hard&&!valid"
|
|
32
|
-
:loading="
|
|
32
|
+
:loading="loading"
|
|
33
33
|
@click.stop="confirm"
|
|
34
34
|
class="color-success-text"
|
|
35
35
|
outlined
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<r-input :class="{
|
|
3
3
|
[`${$r.prefix}checkbox`]:true,
|
|
4
|
-
'checkbox-readonly':
|
|
4
|
+
'checkbox-readonly': readonly,
|
|
5
5
|
}" :modelValue="lazyValue" hide>
|
|
6
6
|
<template v-slot="{isRequired}">
|
|
7
|
-
<div class="
|
|
7
|
+
<div class="checkbox-holder">
|
|
8
8
|
<span class="checkbox-input" :class="{
|
|
9
9
|
[size]:true,
|
|
10
10
|
'br-circle':rounded,
|
|
@@ -102,6 +102,10 @@ const toggle = () => {
|
|
|
102
102
|
width: 100%;
|
|
103
103
|
cursor: pointer;
|
|
104
104
|
|
|
105
|
+
.checkbox-holder{
|
|
106
|
+
display: flex;
|
|
107
|
+
align-items: center;
|
|
108
|
+
}
|
|
105
109
|
.checkbox-label {
|
|
106
110
|
color: var(--color-on-sheet);
|
|
107
111
|
}
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
<div class="file-holder text-center">
|
|
4
4
|
<div v-if="file || modelValue" class="image-canvas">
|
|
5
5
|
<r-btn class="image-close color-white" icon size="xs">
|
|
6
|
-
<r-icon @click.prevent="fileDelete()" class="color-error-text"
|
|
6
|
+
<r-icon @click.prevent="fileDelete()" class="color-error-text"
|
|
7
|
+
v-html="$r.icons.delete"></r-icon>
|
|
7
8
|
</r-btn>
|
|
8
9
|
<r-progress-circle
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
:indeterminate="false"
|
|
11
|
+
:model-value="uploadPercentage"
|
|
12
|
+
:width="2"
|
|
13
|
+
class="image-progress"
|
|
14
|
+
size="50"
|
|
14
15
|
>
|
|
15
16
|
{{ `% ${uploadPercentage}` }}
|
|
16
17
|
</r-progress-circle>
|
|
@@ -25,48 +26,48 @@
|
|
|
25
26
|
</div>
|
|
26
27
|
<div class="file-meta pa-1" v-if="meta && uploadPercentage===100">
|
|
27
28
|
<r-text-input
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
v-for="(m,k) in meta"
|
|
30
|
+
:key="k"
|
|
31
|
+
v-model="metaList[m]"
|
|
32
|
+
:label="$t(m,'renusify')"
|
|
33
|
+
:rules="metaRequired?['required']:[]"
|
|
34
|
+
@update:model-value="emitFileLink"
|
|
34
35
|
></r-text-input>
|
|
35
36
|
</div>
|
|
36
37
|
</div>
|
|
37
38
|
|
|
38
39
|
<r-icon
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
v-if="showAdd"
|
|
41
|
+
class="pick-icon cursor-pointer d-flex h-center v-center color-one-text"
|
|
42
|
+
height="100"
|
|
43
|
+
width="100"
|
|
44
|
+
v-html="$r.icons.plus"
|
|
45
|
+
@click.prevent.stop="pickFile"
|
|
45
46
|
></r-icon>
|
|
46
47
|
<input
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
v-if="showFile"
|
|
49
|
+
ref="fileInput"
|
|
50
|
+
:accept="accept"
|
|
51
|
+
style="display: none"
|
|
52
|
+
type="file"
|
|
53
|
+
@change="addFile"
|
|
53
54
|
>
|
|
54
55
|
<r-modal v-model="showCrop" max-width="300px" no-close-btn>
|
|
55
56
|
<r-cropper
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
57
|
+
v-if="wPH && file"
|
|
58
|
+
:img-src="file"
|
|
59
|
+
:select-img="false"
|
|
60
|
+
:w-p-h="wPH || 1"
|
|
61
|
+
get-blob
|
|
62
|
+
show-cropped
|
|
63
|
+
@cropped="handleCropped"
|
|
63
64
|
></r-cropper>
|
|
64
65
|
</r-modal>
|
|
65
66
|
</div>
|
|
66
67
|
</template>
|
|
67
68
|
|
|
68
69
|
<script setup>
|
|
69
|
-
import {ref, computed, watch, onMounted, nextTick, inject} from 'vue'
|
|
70
|
+
import { ref, computed, watch, onMounted, nextTick, inject } from 'vue'
|
|
70
71
|
|
|
71
72
|
const props = defineProps({
|
|
72
73
|
accept: {
|
|
@@ -106,6 +107,7 @@ const file = ref(null)
|
|
|
106
107
|
const file_type = ref(null)
|
|
107
108
|
const uploadPercentage = ref(0)
|
|
108
109
|
const $axios = inject('axios')
|
|
110
|
+
const $helper = inject('renusify').$helper
|
|
109
111
|
let CancelTokenSource = null
|
|
110
112
|
|
|
111
113
|
// Computed properties
|
|
@@ -200,7 +202,7 @@ const checkSave = () => {
|
|
|
200
202
|
// Calculate allowed aspect ratios
|
|
201
203
|
const allowedWPH = calculateAllowedWPH(props.wPH)
|
|
202
204
|
|
|
203
|
-
img.onload = function
|
|
205
|
+
img.onload = function() {
|
|
204
206
|
const currentWPH = parseFloat((this.width / this.height).toFixed(4))
|
|
205
207
|
|
|
206
208
|
if (!allowedWPH.includes(currentWPH)) {
|
|
@@ -287,8 +289,8 @@ const saveImage = async () => {
|
|
|
287
289
|
onUploadProgress: (progressEvent) => {
|
|
288
290
|
if (progressEvent.total) {
|
|
289
291
|
uploadPercentage.value = Math.min(
|
|
290
|
-
|
|
291
|
-
|
|
292
|
+
parseInt(Math.floor((progressEvent.loaded * 100) / progressEvent.total)),
|
|
293
|
+
98
|
|
292
294
|
)
|
|
293
295
|
}
|
|
294
296
|
},
|
|
@@ -311,7 +313,7 @@ const deleteImage = async () => {
|
|
|
311
313
|
|
|
312
314
|
try {
|
|
313
315
|
const response = await $axios.delete(props.uploadLink, {
|
|
314
|
-
data: {link: fileLink.value},
|
|
316
|
+
data: { link: fileLink.value },
|
|
315
317
|
headers: props.headers
|
|
316
318
|
})
|
|
317
319
|
return response
|
|
@@ -329,7 +331,7 @@ const handleCropped = (croppedFile) => {
|
|
|
329
331
|
|
|
330
332
|
const setValue = (value) => {
|
|
331
333
|
if (value) {
|
|
332
|
-
const fixUrl =
|
|
334
|
+
const fixUrl = $helper?.fix_url || ((url) => url)
|
|
333
335
|
fileLink.value = props.meta ? fixUrl(value['url']) : fixUrl(value)
|
|
334
336
|
metaList.value = props.meta ? value['meta'] : {}
|
|
335
337
|
showAdd.value = false
|
|
@@ -350,7 +352,7 @@ const getUrl = (value) => {
|
|
|
350
352
|
|
|
351
353
|
const emitFileLink = () => {
|
|
352
354
|
if (props.meta) {
|
|
353
|
-
emit('file-link', {'url': fileLink.value, 'meta': metaList.value})
|
|
355
|
+
emit('file-link', { 'url': fileLink.value, 'meta': metaList.value })
|
|
354
356
|
} else {
|
|
355
357
|
emit('file-link', fileLink.value)
|
|
356
358
|
}
|
|
@@ -358,9 +360,12 @@ const emitFileLink = () => {
|
|
|
358
360
|
}
|
|
359
361
|
|
|
360
362
|
// Watch for modelValue changes
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
363
|
+
|
|
364
|
+
watch(() => props.modelValue, (newVal, oldVal) => {
|
|
365
|
+
if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
|
|
366
|
+
setValue(newVal)
|
|
367
|
+
}
|
|
368
|
+
}, { immediate: true })
|
|
364
369
|
|
|
365
370
|
// Initialize
|
|
366
371
|
onMounted(() => {
|
|
@@ -372,4 +377,4 @@ defineExpose({
|
|
|
372
377
|
fileDelete,
|
|
373
378
|
pickFile
|
|
374
379
|
})
|
|
375
|
-
</script>
|
|
380
|
+
</script>
|
|
@@ -146,7 +146,7 @@ const emitValue = () => {
|
|
|
146
146
|
nextTick(() => {
|
|
147
147
|
tel.value.phone = tel.value.phone.replaceAll(' ', '')
|
|
148
148
|
if (tel.value.phone.startsWith('0')) {
|
|
149
|
-
tel.value.phone = tel.value.phone.substring(1,
|
|
149
|
+
tel.value.phone = tel.value.phone.substring(1, tel.value.phone.length)
|
|
150
150
|
emit('update:modelValue', tel.value.country_code + ' ' + tel.value.phone)
|
|
151
151
|
} else {
|
|
152
152
|
emit('update:modelValue', tel.value.country_code + ' ' + tel.value.phone)
|
package/components/img/index.vue
CHANGED
|
@@ -256,13 +256,14 @@ const getSize = () => {
|
|
|
256
256
|
return false
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
const activate = () => {
|
|
259
|
+
const activate = (n=0) => {
|
|
260
|
+
if (n>10)return;
|
|
260
261
|
getSize()
|
|
261
262
|
if (size.value.width !== 0 || size.value.height) {
|
|
262
263
|
load.value = true
|
|
263
264
|
} else {
|
|
264
265
|
nextTick(() => {
|
|
265
|
-
activate()
|
|
266
|
+
activate(n++)
|
|
266
267
|
})
|
|
267
268
|
}
|
|
268
269
|
}
|
|
@@ -3,4 +3,5 @@ export * as l_card from '../card/index.js'
|
|
|
3
3
|
export * as l_container from '../container/index.js'
|
|
4
4
|
export * as l_row from '../container/row.js'
|
|
5
5
|
export * as l_col from '../container/col.js'
|
|
6
|
-
export * as l_switch from '../form/switchInput/index.js'
|
|
6
|
+
export * as l_switch from '../form/switchInput/index.js'
|
|
7
|
+
export * as d_scroll from '../../directive/scroll/index.js'
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<r-container :class="[$r.prefix+'infinite']">
|
|
3
3
|
<div ref="chat"
|
|
4
|
-
v-scroll
|
|
4
|
+
v-scroll="{handler:onScroll,target:target}"
|
|
5
5
|
:style="{'max-height': height,'height': height}"
|
|
6
|
-
class="infinite-page-container">
|
|
6
|
+
class="infinite-page-container" :class="{'overflow-div':height}">
|
|
7
7
|
<transition-group :class="{'flex-column-reverse':isChat}"
|
|
8
8
|
:name="isChat?'slide-up':'slide-down'"
|
|
9
|
-
class="row"
|
|
9
|
+
class="row"
|
|
10
|
+
tag="div">
|
|
10
11
|
<!-- Default slot for contents. Provide items, total props -->
|
|
11
12
|
<slot :items="datacollection" :total="total">{{ datacollection }}</slot>
|
|
13
|
+
<r-col class="col-12" key="loading">
|
|
14
|
+
<r-progress-line color="color-two"
|
|
15
|
+
v-show="loading"></r-progress-line>
|
|
16
|
+
</r-col>
|
|
12
17
|
</transition-group>
|
|
13
18
|
</div>
|
|
14
|
-
<r-progress-line v-show="loading"
|
|
15
|
-
color="color-two"
|
|
16
|
-
|
|
17
|
-
></r-progress-line>
|
|
18
19
|
<div v-if="noItem"
|
|
19
20
|
class="text-center title-2"
|
|
20
21
|
>{{ noItemMsg }}
|
|
@@ -22,7 +23,16 @@
|
|
|
22
23
|
</r-container>
|
|
23
24
|
</template>
|
|
24
25
|
<script setup>
|
|
25
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
ref,
|
|
28
|
+
computed,
|
|
29
|
+
onMounted,
|
|
30
|
+
onUnmounted,
|
|
31
|
+
onActivated,
|
|
32
|
+
onDeactivated,
|
|
33
|
+
watch,
|
|
34
|
+
inject,nextTick
|
|
35
|
+
} from 'vue'
|
|
26
36
|
|
|
27
37
|
const props = defineProps({
|
|
28
38
|
/**
|
|
@@ -125,7 +135,7 @@ const loading = ref(false)
|
|
|
125
135
|
const total = ref(0)
|
|
126
136
|
const noItem = ref(false)
|
|
127
137
|
|
|
128
|
-
const
|
|
138
|
+
const target = computed(() => props.height ? false : 'window')
|
|
129
139
|
|
|
130
140
|
// Methods
|
|
131
141
|
const onScroll = (e) => {
|
|
@@ -145,13 +155,13 @@ const onScroll = (e) => {
|
|
|
145
155
|
}
|
|
146
156
|
}
|
|
147
157
|
} else {
|
|
148
|
-
if (active.value &&
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
if (active.value &&
|
|
159
|
+
(document.body.offsetHeight < ((window.innerHeight + window.scrollY) + props.distanceLoad)) &&
|
|
160
|
+
!loading.value &&
|
|
161
|
+
(datacollection.value.length < total.value)
|
|
162
|
+
) {
|
|
163
|
+
page.value++
|
|
164
|
+
get()
|
|
155
165
|
}
|
|
156
166
|
}
|
|
157
167
|
}
|
|
@@ -161,15 +171,21 @@ const get = () => {
|
|
|
161
171
|
loading.value = true
|
|
162
172
|
noItem.value = false
|
|
163
173
|
|
|
164
|
-
|
|
174
|
+
let end = true
|
|
175
|
+
let params = {'page': page.value}
|
|
176
|
+
|
|
177
|
+
if (props.live === true) {
|
|
178
|
+
params = {'page': 1}
|
|
179
|
+
end = false
|
|
180
|
+
}
|
|
165
181
|
if (typeof props.query === 'object') {
|
|
166
182
|
Object.assign(params, props.query)
|
|
167
183
|
}
|
|
168
184
|
|
|
169
185
|
$axios.get(props.url, {params, headers: props.headers})
|
|
170
|
-
.then((
|
|
171
|
-
push(
|
|
172
|
-
total.value =
|
|
186
|
+
.then(({data}) => {
|
|
187
|
+
push(data.data, end)
|
|
188
|
+
total.value = data.total
|
|
173
189
|
if (total.value === 0) {
|
|
174
190
|
noItem.value = true
|
|
175
191
|
}
|
|
@@ -180,27 +196,48 @@ const get = () => {
|
|
|
180
196
|
})
|
|
181
197
|
}
|
|
182
198
|
|
|
183
|
-
const push = (data) => {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
datacollection.value.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
199
|
+
const push = (data, end = false) => {
|
|
200
|
+
if (!end) {
|
|
201
|
+
let d = data
|
|
202
|
+
const lng = datacollection.value.length
|
|
203
|
+
for (let key = 0; key < lng; key++) {
|
|
204
|
+
if (key <= data.length) {
|
|
205
|
+
if ($helper.searchArray(d, '_id', datacollection.value[key]['_id']) === false) {
|
|
206
|
+
d.push(datacollection.value[key])
|
|
207
|
+
}
|
|
208
|
+
} else {
|
|
209
|
+
d.push(datacollection.value[key])
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
datacollection.value = d
|
|
192
213
|
} else {
|
|
193
|
-
|
|
214
|
+
let d = datacollection.value
|
|
215
|
+
const lng = data.length
|
|
216
|
+
for (let key = 0; key < lng; key++) {
|
|
217
|
+
if ($helper.searchArray(d, '_id', data[key]['_id']) === false) {
|
|
218
|
+
d.push(data[key])
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
datacollection.value = d
|
|
194
222
|
}
|
|
195
|
-
|
|
223
|
+
nextTick(() => {
|
|
224
|
+
let el = chat.value
|
|
225
|
+
let can = false
|
|
226
|
+
if (props.isChat) {
|
|
227
|
+
can = el.scrollHeight <= el.scrollTop + el.clientHeight
|
|
228
|
+
} else {
|
|
229
|
+
can = el.scrollTop === 0
|
|
230
|
+
}
|
|
196
231
|
|
|
197
|
-
if (
|
|
198
|
-
|
|
199
|
-
|
|
232
|
+
if (props.isChat) {
|
|
233
|
+
if (first.value || can) {
|
|
234
|
+
el.scrollTop = el.scrollHeight
|
|
235
|
+
first.value = false
|
|
236
|
+
}
|
|
237
|
+
} else if (can) {
|
|
238
|
+
el.scrollTop = 0
|
|
200
239
|
}
|
|
201
|
-
}
|
|
202
|
-
el.scrollTop = 0;
|
|
203
|
-
}
|
|
240
|
+
})
|
|
204
241
|
}
|
|
205
242
|
|
|
206
243
|
let liveInterval = null
|
|
@@ -231,6 +268,7 @@ onDeactivated(() => {
|
|
|
231
268
|
|
|
232
269
|
watch(() => props.live, (newValue) => {
|
|
233
270
|
if (newValue) {
|
|
271
|
+
get()
|
|
234
272
|
setupLiveUpdates()
|
|
235
273
|
} else {
|
|
236
274
|
clearInterval(liveInterval)
|
|
@@ -248,7 +286,11 @@ onUnmounted(() => {
|
|
|
248
286
|
@use "../../style" as *;
|
|
249
287
|
|
|
250
288
|
.#{$prefix}infinite {
|
|
251
|
-
|
|
252
|
-
|
|
289
|
+
width: 100%;
|
|
290
|
+
|
|
291
|
+
.overflow-div {
|
|
292
|
+
overflow-y: auto;
|
|
293
|
+
overflow-x: hidden;
|
|
294
|
+
}
|
|
253
295
|
}
|
|
254
296
|
</style>
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div ref="menuRef" v-click-outside="close" :class="$r.prefix+'menu'">
|
|
3
3
|
<div class="d-flex h-start flex-row v-center">
|
|
4
|
-
<
|
|
4
|
+
<slot name="label">
|
|
5
|
+
<span class="menu-label" v-if="label" @click.prevent="open">{{ label }}</span>
|
|
6
|
+
</slot>
|
|
5
7
|
<transition name="fade" mode="out-in">
|
|
6
8
|
<!-- Header Navigation Menu Icons -->
|
|
7
|
-
<r-btn icon text v-if="show" key="on" @click.prevent="close">
|
|
9
|
+
<r-btn icon text v-if="show" key="on" size="sm" @click.prevent="close">
|
|
8
10
|
<r-icon v-html="$r.icons.chevron_up"></r-icon>
|
|
9
11
|
</r-btn>
|
|
10
|
-
<r-btn icon text v-else key="off" @click.prevent="open">
|
|
12
|
+
<r-btn icon text v-else key="off" size="sm" @click.prevent="open">
|
|
11
13
|
<r-icon v-html="icon||$r.icons.chevron_down"></r-icon>
|
|
12
14
|
</r-btn>
|
|
13
15
|
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
</template>
|
|
49
49
|
|
|
50
50
|
<script setup>
|
|
51
|
-
import {ref, computed, onMounted, onUnmounted} from 'vue'
|
|
51
|
+
import {ref, computed, onMounted, onUnmounted,watch} from 'vue'
|
|
52
52
|
|
|
53
53
|
/**
|
|
54
54
|
* @example // Slider usage
|
|
@@ -338,6 +338,7 @@ const goToSlide = (i) => {
|
|
|
338
338
|
emit('index', currentIndex.value)
|
|
339
339
|
}
|
|
340
340
|
|
|
341
|
+
watch(()=>props.slides,()=>{init()})
|
|
341
342
|
onMounted(() => {
|
|
342
343
|
init()
|
|
343
344
|
})
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
<div :class="`${$r.prefix}swiper`"
|
|
3
3
|
ref="swiperRef"
|
|
4
4
|
>
|
|
5
|
-
<!-- @slot
|
|
6
|
-
@binding {Function}
|
|
7
|
-
<slot name="
|
|
5
|
+
<!-- @slot Previous navigation slot
|
|
6
|
+
@binding {Function} previous - Function to navigate previous -->
|
|
7
|
+
<slot name="previous" :previous="previous"></slot>
|
|
8
8
|
|
|
9
|
-
<!-- @slot
|
|
10
|
-
@binding {Function}
|
|
11
|
-
<slot name="
|
|
9
|
+
<!-- @slot Next navigation slot
|
|
10
|
+
@binding {Function} next - Function to navigate next -->
|
|
11
|
+
<slot name="next" :next="next"></slot>
|
|
12
12
|
|
|
13
13
|
<div class="swiper-container"
|
|
14
14
|
ref="containerRef"
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
</template>
|
|
50
50
|
|
|
51
51
|
<script setup>
|
|
52
|
-
import {ref, computed, onMounted, onUnmounted, inject, nextTick, watch} from 'vue'
|
|
52
|
+
import { ref, computed, onMounted, onUnmounted, inject, nextTick, watch } from 'vue'
|
|
53
53
|
|
|
54
54
|
/**
|
|
55
55
|
* @example // Swiper usage
|
|
@@ -114,7 +114,7 @@ const props = defineProps({
|
|
|
114
114
|
numShow: [Number, Object]
|
|
115
115
|
})
|
|
116
116
|
|
|
117
|
-
const {$r} = inject('renusify')
|
|
117
|
+
const { $r } = inject('renusify')
|
|
118
118
|
|
|
119
119
|
const timer = ref(null)
|
|
120
120
|
const inMove = ref(false)
|
|
@@ -138,18 +138,6 @@ const itemWidth = computed(() => {
|
|
|
138
138
|
})
|
|
139
139
|
|
|
140
140
|
|
|
141
|
-
const canGoNext = computed(() => {
|
|
142
|
-
const r = $r.rtl ? 1 : -1
|
|
143
|
-
const maxX = (containerRef.value?.scrollWidth - swiperRef.value?.offsetWidth) / r
|
|
144
|
-
return x.value * r < maxX
|
|
145
|
-
})
|
|
146
|
-
|
|
147
|
-
const canGoPrev = computed(() => {
|
|
148
|
-
const r = $r.rtl ? 1 : -1
|
|
149
|
-
return x.value * r > 0
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
|
|
153
141
|
/**
|
|
154
142
|
* Navigates to a specific slide
|
|
155
143
|
* @param {Number} n - Slide number (1-indexed)
|
|
@@ -165,41 +153,19 @@ const goToSlide = (n) => {
|
|
|
165
153
|
}
|
|
166
154
|
|
|
167
155
|
/**
|
|
168
|
-
* Navigates to the next
|
|
169
|
-
* @param {Number|null} customX - Custom distance to move in pixels
|
|
156
|
+
* Navigates to the next slide
|
|
170
157
|
*/
|
|
171
|
-
const
|
|
172
|
-
if
|
|
173
|
-
|
|
174
|
-
const moveX = customX || itemWidth.value || 200
|
|
175
|
-
clearTimeout(timer.value)
|
|
176
|
-
|
|
177
|
-
timer.value = nextTick(() => {
|
|
178
|
-
inMove.value = true
|
|
179
|
-
const direction = $r.rtl ? 1 : -1
|
|
180
|
-
x.value = prePosition.value - (moveX * direction)
|
|
181
|
-
end()
|
|
182
|
-
clearTimeout(timer.value)
|
|
183
|
-
})
|
|
158
|
+
const next = () => {
|
|
159
|
+
if(currentSlide.value+1>slides.value)return
|
|
160
|
+
goToSlide(currentSlide.value+1)
|
|
184
161
|
}
|
|
185
162
|
|
|
186
163
|
/**
|
|
187
|
-
* Navigates to the previous
|
|
188
|
-
* @param {Number|null} customX - Custom distance to move in pixels
|
|
164
|
+
* Navigates to the previous slide
|
|
189
165
|
*/
|
|
190
|
-
const
|
|
191
|
-
if
|
|
192
|
-
|
|
193
|
-
const moveX = customX || itemWidth.value || 200
|
|
194
|
-
clearTimeout(timer.value)
|
|
195
|
-
|
|
196
|
-
timer.value = setTimeout(() => {
|
|
197
|
-
inMove.value = true
|
|
198
|
-
const direction = $r.rtl ? 1 : -1
|
|
199
|
-
x.value = prePosition.value + (moveX * direction)
|
|
200
|
-
end()
|
|
201
|
-
clearTimeout(timer.value)
|
|
202
|
-
}, 50)
|
|
166
|
+
const previous = () => {
|
|
167
|
+
if(currentSlide.value===1)return
|
|
168
|
+
goToSlide(currentSlide.value-1)
|
|
203
169
|
}
|
|
204
170
|
|
|
205
171
|
/**
|
|
@@ -293,7 +259,22 @@ watch(() => props.items, () => {
|
|
|
293
259
|
currentSlide.value = 1
|
|
294
260
|
|
|
295
261
|
handleResize()
|
|
296
|
-
}, {deep: true})
|
|
262
|
+
}, { deep: true })
|
|
263
|
+
|
|
264
|
+
defineExpose({
|
|
265
|
+
/**
|
|
266
|
+
* Navigates to the previous slide
|
|
267
|
+
*/
|
|
268
|
+
previous,
|
|
269
|
+
/**
|
|
270
|
+
* Navigates to the next slide
|
|
271
|
+
*/
|
|
272
|
+
next,
|
|
273
|
+
/**
|
|
274
|
+
* Return Current Slide
|
|
275
|
+
*/
|
|
276
|
+
currentSlide
|
|
277
|
+
})
|
|
297
278
|
</script>
|
|
298
279
|
|
|
299
280
|
<style lang="scss">
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* <div class="scroll-areas">
|
|
6
6
|
* <div class="scroll-area">
|
|
7
7
|
* <h3>Window Scroll</h3>
|
|
8
|
-
* <div v-scroll
|
|
8
|
+
* <div v-scroll="{handler:handleWindowScroll,target:'window'}" class="scroll-content window-scroll">
|
|
9
9
|
* <div class="scroll-info">
|
|
10
10
|
* <div class="info-item">
|
|
11
11
|
* <span>Scroll Top:</span>
|
|
@@ -242,35 +242,39 @@
|
|
|
242
242
|
* }
|
|
243
243
|
* </style>
|
|
244
244
|
* */
|
|
245
|
-
function mounted
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
245
|
+
function mounted(el, binding) {
|
|
246
|
+
let callback = binding.value
|
|
247
|
+
if (typeof binding.value === 'object') {
|
|
248
|
+
binding = binding.value
|
|
249
|
+
callback = binding.handler
|
|
250
|
+
}
|
|
251
|
+
const options = binding.options || {
|
|
252
|
+
passive: true
|
|
253
|
+
}
|
|
250
254
|
let target = el
|
|
251
|
-
if (binding.
|
|
255
|
+
if (binding.target === 'window') {
|
|
252
256
|
target = window
|
|
253
|
-
} else if (binding.
|
|
254
|
-
target = document.querySelector(binding.
|
|
257
|
+
} else if (binding.target) {
|
|
258
|
+
target = document.querySelector(binding.target)
|
|
259
|
+
}
|
|
260
|
+
if (!target) return
|
|
261
|
+
target.addEventListener('scroll', callback, options)
|
|
262
|
+
el._onScroll = {
|
|
263
|
+
callback,
|
|
264
|
+
options,
|
|
265
|
+
target
|
|
255
266
|
}
|
|
256
|
-
if (!target) return
|
|
257
|
-
target.addEventListener('scroll', callback, options)
|
|
258
|
-
el._onScroll = {
|
|
259
|
-
callback,
|
|
260
|
-
options,
|
|
261
|
-
target
|
|
262
|
-
}
|
|
263
267
|
}
|
|
264
268
|
|
|
265
|
-
function unmounted
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
269
|
+
function unmounted(el) {
|
|
270
|
+
if (!el._onScroll) return
|
|
271
|
+
const {
|
|
272
|
+
callback,
|
|
273
|
+
options,
|
|
274
|
+
target
|
|
275
|
+
} = el._onScroll
|
|
276
|
+
target.removeEventListener('scroll', callback, options)
|
|
277
|
+
delete el._onScroll
|
|
274
278
|
}
|
|
275
279
|
|
|
276
280
|
export default {
|
package/index.js
CHANGED
|
@@ -18,38 +18,28 @@ function breakpoint() {
|
|
|
18
18
|
const width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
|
|
19
19
|
const height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
|
|
20
20
|
const points = {
|
|
21
|
-
'
|
|
22
|
-
'sm': 576,
|
|
21
|
+
'sm': 0,
|
|
23
22
|
'md': 768,
|
|
24
|
-
'lg':
|
|
25
|
-
'xl': 1440
|
|
23
|
+
'lg': 1200
|
|
26
24
|
}
|
|
27
25
|
let data = {
|
|
28
26
|
points: points,
|
|
29
|
-
|
|
30
|
-
smOnly: points.sm <= width && width < points.md,
|
|
31
|
-
smAndDown: width < points.md,
|
|
32
|
-
smAndUp: width >= points.sm,
|
|
27
|
+
smOnly: width < points.md,
|
|
33
28
|
mdOnly: points.md <= width && width < points.lg,
|
|
34
29
|
mdAndDown: width < points.lg,
|
|
35
30
|
mdAndUp: width >= points.md,
|
|
36
31
|
lgOnly: points.lg <= width && width < points.xl,
|
|
37
32
|
lgAndDown: width < points.xl,
|
|
38
33
|
lgAndUp: width >= points.lg,
|
|
39
|
-
xlOnly: points.xl <= width,
|
|
40
34
|
width: width,
|
|
41
35
|
height: height
|
|
42
36
|
}
|
|
43
|
-
if (data.
|
|
44
|
-
data.name = 'xs'
|
|
45
|
-
} else if (data.smOnly) {
|
|
37
|
+
if (data.smOnly) {
|
|
46
38
|
data.name = 'sm'
|
|
47
39
|
} else if (data.mdOnly) {
|
|
48
40
|
data.name = 'md'
|
|
49
41
|
} else if (data.lgOnly) {
|
|
50
42
|
data.name = 'lg'
|
|
51
|
-
} else if (data.xlOnly) {
|
|
52
|
-
data.name = 'xl'
|
|
53
43
|
}
|
|
54
44
|
return data
|
|
55
45
|
}
|
package/package.json
CHANGED
|
@@ -25,10 +25,9 @@ $borders: (
|
|
|
25
25
|
$cursor: ('pointer', 'auto', 'grab', 'grabbing') !default;
|
|
26
26
|
|
|
27
27
|
$grid-breakpoints: (
|
|
28
|
-
'
|
|
29
|
-
'
|
|
30
|
-
'
|
|
31
|
-
'lg': 64rem, // Large devices (desktops, 1024px)
|
|
28
|
+
'sm': 0,
|
|
29
|
+
'md': 48rem, // Small devices (tablets, 768px)
|
|
30
|
+
'lg': 75rem, // Large devices (laptops, 1200px)
|
|
32
31
|
) !default;
|
|
33
32
|
|
|
34
33
|
$base-font-size: 1rem;
|
|
@@ -39,10 +38,9 @@ $grid-columns: 12 !default;
|
|
|
39
38
|
$container-padding-x: math.div($grid-gutter, 2) !default;
|
|
40
39
|
|
|
41
40
|
$grid-gutters: (
|
|
42
|
-
'
|
|
43
|
-
'sm': math.div($grid-gutter, 6),
|
|
41
|
+
'sm': math.div($grid-gutter, 12),
|
|
44
42
|
'md': math.div($grid-gutter, 3),
|
|
45
|
-
'lg':$grid-gutter
|
|
43
|
+
'lg':$grid-gutter,
|
|
46
44
|
) !default;
|
|
47
45
|
|
|
48
46
|
$box-shadows: (
|
|
@@ -56,8 +54,8 @@ $box-shadows: (
|
|
|
56
54
|
) !default;
|
|
57
55
|
|
|
58
56
|
$container-max-widths: (
|
|
59
|
-
'md': map.get($grid-breakpoints, 'md')- 3rem,
|
|
60
|
-
'lg': map.get($grid-breakpoints, 'lg')- 4rem
|
|
57
|
+
'md': map.get($grid-breakpoints, 'md') - 3rem,
|
|
58
|
+
'lg': map.get($grid-breakpoints, 'lg') - 4rem
|
|
61
59
|
) !default;
|
|
62
60
|
|
|
63
61
|
$font-weights: (
|
package/tools/icons.js
CHANGED
|
@@ -23,7 +23,7 @@ export let Icons = {
|
|
|
23
23
|
'attachment': '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M7.5 18A5.5 5.5 0 0 1 2 12.5A5.5 5.5 0 0 1 7.5 7H18a4 4 0 0 1 4 4a4 4 0 0 1-4 4H9.5A2.5 2.5 0 0 1 7 12.5A2.5 2.5 0 0 1 9.5 10H17v1.5H9.5a1 1 0 0 0-1 1a1 1 0 0 0 1 1H18a2.5 2.5 0 0 0 2.5-2.5A2.5 2.5 0 0 0 18 8.5H7.5a4 4 0 0 0-4 4a4 4 0 0 0 4 4H17V18H7.5Z"/></svg>',
|
|
24
24
|
'send': '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="m2 21l21-9L2 3v7l15 2l-15 2v7Z"/></svg>',
|
|
25
25
|
'sticker': '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M5.5 2C3.56 2 2 3.56 2 5.5v13C2 20.44 3.56 22 5.5 22H16l6-6V5.5C22 3.56 20.44 2 18.5 2h-13m.25 2h12.5A1.75 1.75 0 0 1 20 5.75V15h-1.5c-1.94 0-3.5 1.56-3.5 3.5V20H5.75A1.75 1.75 0 0 1 4 18.25V5.75A1.75 1.75 0 0 1 5.75 4m8.69 2.77c-.16 0-.32.02-.47.06c-.94.26-1.47 1.22-1.23 2.17c.05.15.12.3.21.44l3.23-.88c0-.17-.02-.34-.06-.51c-.21-.75-.9-1.28-1.68-1.28M8.17 8.5c-.17 0-.32 0-.47.05c-.93.26-1.48 1.22-1.23 2.15c.03.16.12.3.21.46l3.23-.88c0-.17-.02-.34-.06-.5A1.72 1.72 0 0 0 8.17 8.5m8.55 2.76l-9.13 2.51a5.266 5.266 0 0 0 5.36 1.64a5.273 5.273 0 0 0 3.77-4.15Z"/></svg>',
|
|
26
|
-
'search': '<svg xmlns="http://www.w3.org/2000/svg"
|
|
26
|
+
'search': '<svg width="24" height="24" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.25 15.5625C4.215 15.5625 0.9375 12.285 0.9375 8.25C0.9375 4.215 4.215 0.9375 8.25 0.9375C12.285 0.9375 15.5625 4.215 15.5625 8.25C15.5625 12.285 12.285 15.5625 8.25 15.5625ZM8.25 2.0625C4.8375 2.0625 2.0625 4.8375 2.0625 8.25C2.0625 11.6625 4.8375 14.4375 8.25 14.4375C11.6625 14.4375 14.4375 11.6625 14.4375 8.25C14.4375 4.8375 11.6625 2.0625 8.25 2.0625Z" fill="currentColor"/><path d="M15.12 17.0925C15.06 17.0925 15 17.085 14.9475 17.0775C14.595 17.0325 13.9575 16.7925 13.5975 15.72C13.41 15.1575 13.4775 14.595 13.785 14.1675C14.0925 13.74 14.61 13.5 15.2025 13.5C15.9675 13.5 16.5675 13.7925 16.8375 14.31C17.1075 14.8275 17.0325 15.4875 16.605 16.125C16.0725 16.9275 15.495 17.0925 15.12 17.0925ZM14.67 15.3675C14.7975 15.7575 14.9775 15.9525 15.0975 15.9675C15.2175 15.9825 15.4425 15.84 15.675 15.5025C15.8925 15.18 15.9075 14.9475 15.855 14.8425C15.8025 14.7375 15.5925 14.625 15.2025 14.625C14.97 14.625 14.7975 14.7 14.7 14.8275C14.61 14.955 14.595 15.15 14.67 15.3675Z" fill="currentColor"/></svg>',
|
|
27
27
|
'drag': '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M7 19v-2h2v2H7m4 0v-2h2v2h-2m4 0v-2h2v2h-2m-8-4v-2h2v2H7m4 0v-2h2v2h-2m4 0v-2h2v2h-2m-8-4V9h2v2H7m4 0V9h2v2h-2m4 0V9h2v2h-2M7 7V5h2v2H7m4 0V5h2v2h-2m4 0V5h2v2h-2Z"/></svg>',
|
|
28
28
|
'setting': '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M19.14 12.94c.04-.3.06-.61.06-.94c0-.32-.02-.64-.07-.94l2.03-1.58a.49.49 0 0 0 .12-.61l-1.92-3.32a.488.488 0 0 0-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54a.484.484 0 0 0-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58a.49.49 0 0 0-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6s3.6 1.62 3.6 3.6s-1.62 3.6-3.6 3.6z"/></svg>',
|
|
29
29
|
'star': '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><path fill="currentColor" d="M12 17.27L18.18 21l-1.64-7.03L22 9.24l-7.19-.62L12 2L9.19 8.62L2 9.24l5.45 4.73L5.82 21L12 17.27Z"/></svg>',
|