@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.
@@ -238,6 +238,7 @@ async function disableDrag() {
238
238
  }
239
239
 
240
240
  function startDrag(e: MouseEvent) {
241
+ e.stopPropagation()
241
242
  if (e.button !== 0 || !props.freeDrag || !isSliderAvailable) return
242
243
 
243
244
  clearAutoplay()
@@ -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>
@@ -147,7 +147,6 @@ onUnmounted(() => {
147
147
  display: flex;
148
148
  justify-content: space-between;
149
149
  align-items: center;
150
- gap: 0;
151
150
  }
152
151
  .modal-no-title{
153
152
  width: calc(100% + 2rem);
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" setup>
2
- import type { BglFormSchemaFnT, BtnOptions, BagelForm } from '@bagelink/vue'
3
- import { Btn, Modal, useBagel, BagelForm2 } from '@bagelink/vue'
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
- <BagelForm2
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
- <Btn value="Submit" @click="runSubmit" />
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
- const translateXValue = containerWidth * animTranslateX
70
- const translateYValue = containerHeight * animTranslateY
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 { x: (scale - 1) / 2, y: translateLimitY }
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 { x: translateLimitX, y: (scale - 1) / 2 }
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 BagelForm2 } from './BagelForm.vue'
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}`) || 0)
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 += step
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 -= step
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
- <p
188
- v-lightbox="{ src: pathToUrl(path_key), download: true }"
189
- class="ellipsis-1 word-break-all h-20 m-0"
190
- >
191
- {{ path_key.split('/').pop() }}
192
- </p>
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
- currentItem = item
15
- if (groupItems === undefined) return
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="navigation-btn oval"
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="navigation-btn oval"
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
- <div class="bgl-lightbox-item">
117
- <template v-if="currentItem?.type === 'image'">
118
- <Zoomer v-model:zoom="zoom" :disabled="!currentItem?.enableZoom" :mouse-wheel-to-zoom="false">
119
- <Image :draggable="false" :src="currentItem?.src" alt="Preview" class="vw90 lightbox-image" />
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
- </template>
122
- <template v-else-if="currentItem?.type === 'video'">
122
+
123
123
  <BglVideo
124
- :src="currentItem?.src"
124
+ v-else-if="item?.type === 'video'"
125
+ :src="item?.src"
125
126
  autoplay
126
127
  controls
127
128
  class="vw90"
128
129
  />
129
- </template>
130
- <template v-else-if="currentItem?.type === 'pdf'">
130
+
131
131
  <embed
132
- :src="normalizeURL(currentItem?.src)"
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="currentItem?.name"
137
+ :title="item?.name"
137
138
  class="vw90"
138
139
  >
139
- </template>
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
- {{ currentItem?.name }}
148
+ {{ item?.name }}
150
149
  </span>
151
150
  </p>
152
151
  <p class="mx-0 ">
153
152
  Type:
154
153
  <span class="semi">
155
- {{ currentItem?.type }}
154
+ {{ item?.type }}
156
155
  </span>
157
156
  </p>
158
- <Btn :href="currentItem?.src" target="_blank" round thin class="mt-1" value="Open file" />
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
- </div>
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;
@@ -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