@bagelink/vue 0.0.1143 → 0.0.1145
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.map +1 -1
- package/dist/components/Modal.vue.d.ts.map +1 -1
- package/dist/components/Zoomer.vue.d.ts.map +1 -1
- package/dist/components/form/index.d.ts +2 -3
- package/dist/components/form/index.d.ts.map +1 -1
- package/dist/components/form/inputs/FileUpload.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/composables/useEditor.d.ts.map +1 -1
- package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts.map +1 -1
- package/dist/components/lightbox/Lightbox.vue.d.ts.map +1 -1
- package/dist/index.cjs +467 -548
- package/dist/index.mjs +467 -548
- package/dist/plugins/modal.d.ts +5 -0
- package/dist/plugins/modal.d.ts.map +1 -1
- package/dist/style.css +121 -115
- package/package.json +1 -1
- package/src/components/Carousel.vue +1 -0
- package/src/components/Icon/Icon.vue +1 -1
- package/src/components/Modal.vue +0 -1
- package/src/components/ModalForm.vue +24 -19
- package/src/components/Zoomer.vue +24 -4
- package/src/components/form/index.ts +2 -3
- package/src/components/form/inputs/FileUpload.vue +12 -1
- package/src/components/form/inputs/NumberInput.vue +6 -6
- package/src/components/form/inputs/Upload/UploadInput.vue +9 -6
- package/src/components/lightbox/Lightbox.vue +32 -33
- package/src/plugins/modal.ts +5 -0
|
@@ -31,7 +31,7 @@ const isFaBrand = $computed(() => FONT_AWESOME_BRANDS_ICONS.includes(iconRender)
|
|
|
31
31
|
</span>
|
|
32
32
|
<i
|
|
33
33
|
v-else-if="iconRenderType === 'font-awesome'"
|
|
34
|
-
class="fa" :class="[`fa-${iconRender}`, { 'fa-brands': isFaBrand }]"
|
|
34
|
+
class="fa far" :class="[`fa-${iconRender}`, { 'fa-brands': isFaBrand }]"
|
|
35
35
|
:style="{ 'fontSize': `${size}rem`, color, 'font-variation-settings': `'wght' ${weight || 400}` }"
|
|
36
36
|
/>
|
|
37
37
|
</template>
|
package/src/components/Modal.vue
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import type { BglFormSchemaFnT, BtnOptions
|
|
3
|
-
import { Btn, Modal, useBagel,
|
|
2
|
+
import type { BglFormSchemaFnT, BtnOptions } from '@bagelink/vue'
|
|
3
|
+
import { Btn, Modal, useBagel, BagelForm } from '@bagelink/vue'
|
|
4
4
|
|
|
5
5
|
const props = defineProps<{
|
|
6
6
|
side?: boolean
|
|
@@ -11,13 +11,14 @@ const props = defineProps<{
|
|
|
11
11
|
schema: BglFormSchemaFnT<any>
|
|
12
12
|
|
|
13
13
|
onSubmit?: (formData: any) => Promise<void>
|
|
14
|
-
|
|
14
|
+
onDuplicate?: (formData: any) => Promise<void>
|
|
15
|
+
submitText?: string
|
|
16
|
+
cancelText?: string
|
|
17
|
+
deleteText?: string
|
|
18
|
+
duplicateText?: string
|
|
15
19
|
onDelete?: (id: string) => void
|
|
16
|
-
|
|
17
20
|
visible?: boolean
|
|
18
|
-
|
|
19
21
|
onError?: (err: any) => void
|
|
20
|
-
|
|
21
22
|
modelValue?: { [key: string]: any }
|
|
22
23
|
}>()
|
|
23
24
|
|
|
@@ -76,34 +77,38 @@ defineExpose({ setFormValues })
|
|
|
76
77
|
:title
|
|
77
78
|
@update:visible="($event: boolean) => emit('update:visible', $event)"
|
|
78
79
|
>
|
|
79
|
-
<
|
|
80
|
+
<BagelForm
|
|
80
81
|
v-if="visible"
|
|
81
82
|
ref="form"
|
|
82
83
|
v-model="formData"
|
|
83
84
|
:schema="computedFormSchema"
|
|
84
85
|
@submit="runSubmit"
|
|
85
86
|
/>
|
|
86
|
-
<!-- <BagelForm
|
|
87
|
-
v-if="visible"
|
|
88
|
-
ref="form"
|
|
89
|
-
v-model="formData"
|
|
90
|
-
:schema="computedFormSchema"
|
|
91
|
-
@submit="runSubmit"
|
|
92
|
-
/> -->
|
|
93
87
|
<template v-if="onDelete || onSubmit" #footer>
|
|
94
|
-
<div>
|
|
95
|
-
<Btn thin flat value="Cancel" @click="closeModal" />
|
|
88
|
+
<div class="flex gap-0">
|
|
89
|
+
<Btn thin flat :value="cancelText || 'Cancel'" @click="closeModal" />
|
|
96
90
|
<Btn
|
|
97
|
-
v-if="onDelete"
|
|
91
|
+
v-if="onDelete && formData.id"
|
|
98
92
|
thin
|
|
99
93
|
icon="delete"
|
|
100
94
|
flat
|
|
101
|
-
value="Delete"
|
|
95
|
+
:value="deleteText || 'Delete'"
|
|
102
96
|
color="red"
|
|
103
97
|
@click="runDelete"
|
|
104
98
|
/>
|
|
105
99
|
</div>
|
|
106
|
-
<
|
|
100
|
+
<div class="flex gap-05">
|
|
101
|
+
<Btn
|
|
102
|
+
v-if="onDuplicate"
|
|
103
|
+
outline
|
|
104
|
+
class="px-1"
|
|
105
|
+
icon="copy_all"
|
|
106
|
+
flat
|
|
107
|
+
:value="duplicateText || 'Duplicate'"
|
|
108
|
+
@click="onDuplicate"
|
|
109
|
+
/>
|
|
110
|
+
<Btn v-if="onSubmit" :value="submitText || 'Submit'" @click="runSubmit" />
|
|
111
|
+
</div>
|
|
107
112
|
</template>
|
|
108
113
|
</Modal>
|
|
109
114
|
</template>
|
|
@@ -65,9 +65,12 @@ let panLocked = $ref(true)
|
|
|
65
65
|
let raf = $ref<number | undefined>()
|
|
66
66
|
let tapDetector = $ref<TapDetector | undefined>()
|
|
67
67
|
|
|
68
|
+
let translateXValue = $ref(0)
|
|
69
|
+
let translateYValue = $ref(0)
|
|
70
|
+
|
|
68
71
|
const wrapperStyle = $computed(() => {
|
|
69
|
-
|
|
70
|
-
|
|
72
|
+
translateXValue = containerWidth * animTranslateX
|
|
73
|
+
translateYValue = containerHeight * animTranslateY
|
|
71
74
|
return {
|
|
72
75
|
transform: [
|
|
73
76
|
`translate(${translateXValue}px, ${translateYValue}px)`,
|
|
@@ -169,12 +172,18 @@ function calcTranslateLimit() {
|
|
|
169
172
|
const imageToContainerRatio = containerWidth / aspectRatio / containerHeight
|
|
170
173
|
let translateLimitY = (scale * imageToContainerRatio - 1) / 2
|
|
171
174
|
if (translateLimitY < 0) translateLimitY = 0
|
|
172
|
-
return {
|
|
175
|
+
return {
|
|
176
|
+
x: scale - 1, // Allow full movement to edges horizontally
|
|
177
|
+
y: translateLimitY * 2 // Allow full movement to edges vertically
|
|
178
|
+
}
|
|
173
179
|
}
|
|
174
180
|
const imageToContainerRatio = containerHeight * aspectRatio / containerWidth
|
|
175
181
|
let translateLimitX = (scale * imageToContainerRatio - 1) / 2
|
|
176
182
|
if (translateLimitX < 0) translateLimitX = 0
|
|
177
|
-
return {
|
|
183
|
+
return {
|
|
184
|
+
x: translateLimitX * 2, // Allow full movement to edges horizontally
|
|
185
|
+
y: scale - 1 // Allow full movement to edges vertically
|
|
186
|
+
}
|
|
178
187
|
}
|
|
179
188
|
|
|
180
189
|
function getMarginDirection() {
|
|
@@ -353,6 +362,15 @@ function onWindowResize() {
|
|
|
353
362
|
</template>
|
|
354
363
|
|
|
355
364
|
<style scoped>
|
|
365
|
+
.zoomer-debug {
|
|
366
|
+
position: fixed;
|
|
367
|
+
top: 0;
|
|
368
|
+
right: 0;
|
|
369
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
370
|
+
color: white;
|
|
371
|
+
z-index: 1000;
|
|
372
|
+
height: 100px
|
|
373
|
+
}
|
|
356
374
|
.vue-zoomer {
|
|
357
375
|
overflow: hidden;
|
|
358
376
|
}
|
|
@@ -360,6 +378,8 @@ function onWindowResize() {
|
|
|
360
378
|
transform-origin: 50% 50%;
|
|
361
379
|
width: 100%;
|
|
362
380
|
height: 100%;
|
|
381
|
+
max-width: 100vw;
|
|
382
|
+
max-height: 100vh;
|
|
363
383
|
}
|
|
364
384
|
.zoomer > img {
|
|
365
385
|
vertical-align: top;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
export { default as
|
|
1
|
+
export { default as BglForm } from './BagelForm.vue'
|
|
2
|
+
export { default as BagelForm } from './BagelForm.vue'
|
|
2
3
|
export { default as BglField } from './BglField.vue'
|
|
3
|
-
export { default as BglForm } from './BglForm.vue'
|
|
4
|
-
export { default as BagelForm } from './BglForm.vue'
|
|
5
4
|
export { default as FieldArray } from './FieldArray.vue'
|
|
6
5
|
export * from './inputs'
|
|
@@ -295,10 +295,21 @@ function drop(e: DragEvent) {
|
|
|
295
295
|
/>
|
|
296
296
|
<p
|
|
297
297
|
v-lightbox="{ src: file.url, download: true }"
|
|
298
|
-
class="ellipsis-1 word-break-all h-20 m-0"
|
|
298
|
+
class="ellipsis-1 word-break-all h-20 m-0 color-black"
|
|
299
299
|
>
|
|
300
300
|
{{ file.name }}
|
|
301
301
|
</p>
|
|
302
|
+
|
|
303
|
+
<div class="flex gap-025 rounded pe-1 ps-05 py-025 bg-gray-80 -my-1 ">
|
|
304
|
+
<Icon icon="draft" :size="1.5" />
|
|
305
|
+
<p
|
|
306
|
+
v-lightbox="{ src: file.url, download: true }"
|
|
307
|
+
class="ellipsis-1 word-break-all h-20 m-0 color-black txt18"
|
|
308
|
+
>
|
|
309
|
+
{{ file.name }}
|
|
310
|
+
</p>
|
|
311
|
+
</div>
|
|
312
|
+
|
|
302
313
|
<Btn
|
|
303
314
|
thin
|
|
304
315
|
flat
|
|
@@ -44,23 +44,23 @@ const {
|
|
|
44
44
|
|
|
45
45
|
const emit = defineEmits(['update:modelValue'])
|
|
46
46
|
|
|
47
|
-
let numberValue = $ref(Number.parseFloat(`${modelValue}`) ||
|
|
47
|
+
let numberValue = $ref(Number.parseFloat(`${modelValue}`) || undefined)
|
|
48
48
|
|
|
49
49
|
const btnLayouts: NumberLayout[] = ['horizontal', 'vertical']
|
|
50
50
|
|
|
51
|
-
const canAdd = $computed(() => !(max !== undefined && (numberValue + step) > max))
|
|
52
|
-
const canDecrement = $computed(() => !(min !== undefined && (numberValue - step) < min))
|
|
51
|
+
const canAdd = $computed(() => !(max !== undefined && (numberValue || 0 + step) > max))
|
|
52
|
+
const canDecrement = $computed(() => !(min !== undefined && (numberValue || 0 - step) < min))
|
|
53
53
|
|
|
54
54
|
// Methods
|
|
55
55
|
function increment() {
|
|
56
56
|
if (!canAdd) return
|
|
57
|
-
numberValue
|
|
57
|
+
numberValue = (numberValue || 0) + step
|
|
58
58
|
emit('update:modelValue', numberValue)
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
function decrement() {
|
|
62
62
|
if (!canDecrement) return
|
|
63
|
-
numberValue
|
|
63
|
+
numberValue = (numberValue || 0) - step
|
|
64
64
|
emit('update:modelValue', numberValue)
|
|
65
65
|
}
|
|
66
66
|
|
|
@@ -84,7 +84,7 @@ function inputHandler() {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
watch(() => numberValue, () => {
|
|
87
|
-
formattedValue = formatNumber(numberValue)
|
|
87
|
+
formattedValue = numberValue !== undefined ? formatNumber(numberValue) : ''
|
|
88
88
|
}, { immediate: true })
|
|
89
89
|
|
|
90
90
|
watch(() => modelValue, (newVal) => {
|
|
@@ -184,12 +184,15 @@ watch(() => props.dirPath, () => {
|
|
|
184
184
|
:href="pathToUrl(path_key)"
|
|
185
185
|
:download="path_key.split('/').pop()"
|
|
186
186
|
/>
|
|
187
|
-
<
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
187
|
+
<div class="flex gap-025 rounded pe-1 ps-05 py-025 bg-gray-80 -my-1 ">
|
|
188
|
+
<Icon icon="draft" :size="1.5" />
|
|
189
|
+
<p
|
|
190
|
+
v-lightbox="{ src: pathToUrl(path_key), download: true }"
|
|
191
|
+
class="ellipsis-1 word-break-all h-20 m-0 color-black txt18"
|
|
192
|
+
>
|
|
193
|
+
{{ path_key.split('/').pop() }}
|
|
194
|
+
</p>
|
|
195
|
+
</div>
|
|
193
196
|
</div>
|
|
194
197
|
</div>
|
|
195
198
|
</template>
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { LightboxItem } from './lightbox.types'
|
|
3
3
|
|
|
4
|
-
import { BglVideo, Btn, Icon, Zoomer, Image, normalizeURL } from '@bagelink/vue'
|
|
4
|
+
import { BglVideo, Btn, Icon, Zoomer, Image, normalizeURL, Carousel } from '@bagelink/vue'
|
|
5
5
|
import { watch } from 'vue'
|
|
6
6
|
|
|
7
7
|
let isOpen = $ref(false)
|
|
8
|
-
let currentItem = $ref<LightboxItem>()
|
|
9
8
|
let group = $ref<LightboxItem[]>([])
|
|
10
9
|
let currentIndex = $ref(0)
|
|
10
|
+
let currentItem = $computed<LightboxItem>(() => group[currentIndex])
|
|
11
11
|
|
|
12
12
|
function open(item: LightboxItem, groupItems?: LightboxItem[]) {
|
|
13
13
|
isOpen = true
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
group = groupItems
|
|
17
|
-
currentIndex = groupItems.findIndex(({ src }) => item.src === src)
|
|
14
|
+
group = groupItems || [item]
|
|
15
|
+
currentIndex = group.findIndex(({ src }) => item.src === src)
|
|
18
16
|
document.addEventListener('keydown', handleKeydown)
|
|
19
17
|
}
|
|
20
18
|
|
|
@@ -78,16 +76,18 @@ defineExpose({ open, close })
|
|
|
78
76
|
@keydown.right="next"
|
|
79
77
|
@click="clickOutside"
|
|
80
78
|
>
|
|
81
|
-
<div v-if="group && group.length > 1" class="navigation flex space-between px-3 w-100 absolute m_px-1">
|
|
79
|
+
<div v-if="group && group.length > 1" class="navigation flex space-between px-3 w-100 absolute m_px-1 m_none z-9">
|
|
82
80
|
<Btn
|
|
83
|
-
class="
|
|
81
|
+
class="oval opacity-8"
|
|
84
82
|
icon="arrow_back"
|
|
83
|
+
color="black"
|
|
85
84
|
@click="prev"
|
|
86
85
|
/>
|
|
87
86
|
|
|
88
87
|
<Btn
|
|
89
|
-
class="
|
|
88
|
+
class="oval opacity-8"
|
|
90
89
|
icon="arrow_forward"
|
|
90
|
+
color="black"
|
|
91
91
|
@click="next"
|
|
92
92
|
/>
|
|
93
93
|
</div>
|
|
@@ -113,32 +113,31 @@ defineExpose({ open, close })
|
|
|
113
113
|
/>
|
|
114
114
|
<div v-if="!currentItem?.openFile && !currentItem?.download" />
|
|
115
115
|
</div>
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
|
|
117
|
+
<Carousel v-model:index="currentIndex" :items="1" class="bgl-lightbox-item" :class="{ zoomed: zoom > 1 }" :freeDrag="zoom === 1">
|
|
118
|
+
<template v-for="item in group" :key="item.src">
|
|
119
|
+
<Zoomer v-if="item.type === 'image'" v-model:zoom="zoom" :disabled="!item?.enableZoom" :mouse-wheel-to-zoom="false">
|
|
120
|
+
<Image :draggable="false" :src="item?.src" alt="Preview" class="vw90 lightbox-image" />
|
|
120
121
|
</Zoomer>
|
|
121
|
-
|
|
122
|
-
<template v-else-if="currentItem?.type === 'video'">
|
|
122
|
+
|
|
123
123
|
<BglVideo
|
|
124
|
-
|
|
124
|
+
v-else-if="item?.type === 'video'"
|
|
125
|
+
:src="item?.src"
|
|
125
126
|
autoplay
|
|
126
127
|
controls
|
|
127
128
|
class="vw90"
|
|
128
129
|
/>
|
|
129
|
-
|
|
130
|
-
<template v-else-if="currentItem?.type === 'pdf'">
|
|
130
|
+
|
|
131
131
|
<embed
|
|
132
|
-
|
|
132
|
+
v-else-if="item?.type === 'pdf'"
|
|
133
|
+
:src="normalizeURL(item?.src)"
|
|
133
134
|
type="application/pdf"
|
|
134
135
|
width="100%"
|
|
135
136
|
height="1080"
|
|
136
|
-
:title="
|
|
137
|
+
:title="item?.name"
|
|
137
138
|
class="vw90"
|
|
138
139
|
>
|
|
139
|
-
|
|
140
|
-
<template v-else>
|
|
141
|
-
<div class="file-info txt-white flex m_block align-items-start gap-025">
|
|
140
|
+
<div v-else class="file-info txt-white flex m_block align-items-start gap-025">
|
|
142
141
|
<Icon class="m-0 m_none" icon="draft" :size="10" weight="12" />
|
|
143
142
|
<Icon class="m-0 none m_block m_-mb-1" icon="draft" :size="4" weight="2" />
|
|
144
143
|
|
|
@@ -146,21 +145,21 @@ defineExpose({ open, close })
|
|
|
146
145
|
<p class="mx-0 light">
|
|
147
146
|
File:
|
|
148
147
|
<span class="semi word-break-all ">
|
|
149
|
-
{{
|
|
148
|
+
{{ item?.name }}
|
|
150
149
|
</span>
|
|
151
150
|
</p>
|
|
152
151
|
<p class="mx-0 ">
|
|
153
152
|
Type:
|
|
154
153
|
<span class="semi">
|
|
155
|
-
{{
|
|
154
|
+
{{ item?.type }}
|
|
156
155
|
</span>
|
|
157
156
|
</p>
|
|
158
|
-
<Btn :href="
|
|
157
|
+
<Btn :href="item?.src" target="_blank" round thin class="mt-1" value="Open file" />
|
|
159
158
|
<!-- <a :href="currentItem?.src" target="_blank">Open file</a> -->
|
|
160
159
|
</div>
|
|
161
160
|
</div>
|
|
162
161
|
</template>
|
|
163
|
-
</
|
|
162
|
+
</Carousel>
|
|
164
163
|
<div
|
|
165
164
|
v-if="group && group.length > 1"
|
|
166
165
|
class="flex justify-content-center mt-2 overflow
|
|
@@ -222,11 +221,16 @@ defineExpose({ open, close })
|
|
|
222
221
|
}
|
|
223
222
|
|
|
224
223
|
.bgl-lightbox-item * {
|
|
225
|
-
max-width: 90%;
|
|
226
224
|
max-height: calc(80vh - 90px);
|
|
227
225
|
border-radius: 3px;
|
|
228
226
|
margin: auto;
|
|
229
227
|
animation: 200ms ease bgl-lightbox-load;
|
|
228
|
+
transition: max-height 200ms ease;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.bgl-lightbox-item.zoomed * {
|
|
232
|
+
max-height: calc(100vh - 90px);
|
|
233
|
+
height: calc(100vh - 90px);
|
|
230
234
|
}
|
|
231
235
|
|
|
232
236
|
.navigation {
|
|
@@ -234,11 +238,6 @@ defineExpose({ open, close })
|
|
|
234
238
|
transform: translateY(-50%);
|
|
235
239
|
}
|
|
236
240
|
|
|
237
|
-
.navigation-btn {
|
|
238
|
-
width: var(--input-height);
|
|
239
|
-
height: var(--input-height);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
241
|
.thumbnail {
|
|
243
242
|
height: 50px;
|
|
244
243
|
width: 50px;
|
package/src/plugins/modal.ts
CHANGED
|
@@ -17,7 +17,12 @@ export interface ModalOptions {
|
|
|
17
17
|
export interface ModalFormOptions extends ModalOptions {
|
|
18
18
|
'schema': BglFormSchemaFnT<any>
|
|
19
19
|
'onSubmit'?: (formData: any) => any
|
|
20
|
+
'submitText'?: string
|
|
21
|
+
'cancelText'?: string
|
|
22
|
+
'deleteText'?: string
|
|
23
|
+
'duplicateText'?: string
|
|
20
24
|
'onDelete'?: (id: string) => Promise<void>
|
|
25
|
+
'onDuplicate'?: (formData: any) => Promise<void>
|
|
21
26
|
'onError'?: (err: any) => void
|
|
22
27
|
'modelValue'?: { [key: string]: any }
|
|
23
28
|
'onUpdate:modelValue'?: (val: any) => void
|