@bagelink/vue 1.6.47 → 1.6.51

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.
Files changed (170) hide show
  1. package/bin/experimentalGenTypedRoutes.ts +18 -19
  2. package/bin/utils.ts +4 -4
  3. package/dist/components/AddressSearch.vue.d.ts.map +1 -1
  4. package/dist/components/Alert.vue.d.ts.map +1 -1
  5. package/dist/components/BglVideo.vue.d.ts.map +1 -1
  6. package/dist/components/Card.vue.d.ts.map +1 -1
  7. package/dist/components/Carousel.vue.d.ts +2 -2
  8. package/dist/components/Carousel.vue.d.ts.map +1 -1
  9. package/dist/components/Dropdown.vue.d.ts.map +1 -1
  10. package/dist/components/Flag.vue.d.ts.map +1 -1
  11. package/dist/components/IframeVue.vue.d.ts.map +1 -1
  12. package/dist/components/ListItem.vue.d.ts.map +1 -1
  13. package/dist/components/Loading.vue.d.ts.map +1 -1
  14. package/dist/components/Modal.vue.d.ts.map +1 -1
  15. package/dist/components/ModalForm.vue.d.ts.map +1 -1
  16. package/dist/components/NavBar.vue.d.ts +1 -1
  17. package/dist/components/Pill.vue.d.ts.map +1 -1
  18. package/dist/components/Zoomer.vue.d.ts +0 -1
  19. package/dist/components/Zoomer.vue.d.ts.map +1 -1
  20. package/dist/components/analytics/LineChart.vue.d.ts.map +1 -1
  21. package/dist/components/analytics/PieChart.vue.d.ts +2 -1
  22. package/dist/components/analytics/PieChart.vue.d.ts.map +1 -1
  23. package/dist/components/analytics/index.d.ts +1 -1
  24. package/dist/components/analytics/index.d.ts.map +1 -1
  25. package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
  26. package/dist/components/form/BglMultiStepForm.vue.d.ts.map +1 -1
  27. package/dist/components/form/inputs/ColorInput.vue.d.ts.map +1 -1
  28. package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
  29. package/dist/components/form/inputs/PasswordInput.vue.d.ts.map +1 -1
  30. package/dist/components/form/inputs/RadioGroup.vue.d.ts.map +1 -1
  31. package/dist/components/form/inputs/RangeInput.vue.d.ts +11 -11
  32. package/dist/components/form/inputs/RichText/components/EditorToolbar.vue.d.ts.map +1 -1
  33. package/dist/components/form/inputs/RichText/components/TableGridSelector.vue.d.ts.map +1 -1
  34. package/dist/components/form/inputs/RichText/utils/commands.d.ts.map +1 -1
  35. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  36. package/dist/components/form/inputs/TelInput.vue.d.ts.map +1 -1
  37. package/dist/components/layout/AppSidebar.vue.d.ts +1 -0
  38. package/dist/components/layout/AppSidebar.vue.d.ts.map +1 -1
  39. package/dist/components/layout/Layout.vue.d.ts.map +1 -1
  40. package/dist/components/layout/Tabs.vue.d.ts.map +1 -1
  41. package/dist/components/layout/index.d.ts +3 -3
  42. package/dist/components/layout/index.d.ts.map +1 -1
  43. package/dist/index.cjs +34 -25
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.mjs +6668 -5883
  47. package/dist/plugins/useToast.d.ts.map +1 -1
  48. package/dist/style.css +1 -1
  49. package/package.json +5 -10
  50. package/src/components/AccordionItem.vue +11 -11
  51. package/src/components/AddToCalendar.vue +1 -1
  52. package/src/components/AddressSearch.vue +9 -8
  53. package/src/components/Alert.vue +2 -1
  54. package/src/components/Badge.vue +5 -5
  55. package/src/components/BglVideo.vue +44 -45
  56. package/src/components/Btn.vue +15 -15
  57. package/src/components/Card.vue +10 -8
  58. package/src/components/Carousel.vue +159 -162
  59. package/src/components/DataPreview.vue +1 -1
  60. package/src/components/DragOver.vue +6 -6
  61. package/src/components/Dropdown.vue +39 -38
  62. package/src/components/Flag.vue +7 -6
  63. package/src/components/Icon/Icon.vue +22 -22
  64. package/src/components/IframeVue.vue +5 -5
  65. package/src/components/Image.vue +17 -17
  66. package/src/components/ImportData.vue +79 -79
  67. package/src/components/ListItem.vue +20 -13
  68. package/src/components/Loading.vue +10 -9
  69. package/src/components/MapEmbed/Index.vue +24 -24
  70. package/src/components/Modal.vue +11 -9
  71. package/src/components/ModalForm.vue +9 -8
  72. package/src/components/NavBar.vue +6 -6
  73. package/src/components/Pagination.vue +27 -27
  74. package/src/components/Pill.vue +11 -12
  75. package/src/components/Rating.vue +2 -2
  76. package/src/components/Slider.vue +75 -75
  77. package/src/components/Spreadsheet/Index.vue +34 -34
  78. package/src/components/Spreadsheet/SpreadsheetTable.vue +3 -3
  79. package/src/components/Zoomer.vue +165 -170
  80. package/src/components/analytics/BarChart.vue +6 -6
  81. package/src/components/analytics/KpiCard.vue +2 -2
  82. package/src/components/analytics/LineChart.vue +63 -61
  83. package/src/components/analytics/PieChart.vue +104 -90
  84. package/src/components/analytics/index.ts +2 -2
  85. package/src/components/calendar/CalendarPopover.vue +1 -1
  86. package/src/components/calendar/Index.vue +1 -1
  87. package/src/components/calendar/views/AgendaView.vue +3 -3
  88. package/src/components/calendar/views/DayView.vue +6 -6
  89. package/src/components/calendar/views/MonthView.vue +2 -2
  90. package/src/components/calendar/views/WeekView.vue +18 -18
  91. package/src/components/dataTable/DataTable.vue +4 -4
  92. package/src/components/dataTable/useSorting.ts +1 -1
  93. package/src/components/dataTable/useTableData.ts +15 -15
  94. package/src/components/dataTable/useTableSelection.ts +15 -15
  95. package/src/components/dataTable/useTableVirtualization.ts +1 -1
  96. package/src/components/draggable/useDraggable.ts +42 -42
  97. package/src/components/form/BagelForm.vue +15 -15
  98. package/src/components/form/BglFieldSet.vue +5 -3
  99. package/src/components/form/BglMultiStepForm.vue +20 -21
  100. package/src/components/form/inputs/CheckInput.vue +2 -2
  101. package/src/components/form/inputs/CodeEditor/format.ts +7 -7
  102. package/src/components/form/inputs/CodeEditor/useHighlight.ts +6 -6
  103. package/src/components/form/inputs/ColorInput.vue +5 -4
  104. package/src/components/form/inputs/DateInput.vue +8 -9
  105. package/src/components/form/inputs/DatePicker.vue +24 -24
  106. package/src/components/form/inputs/EmailInput.vue +24 -24
  107. package/src/components/form/inputs/NumberInput.vue +26 -26
  108. package/src/components/form/inputs/OTP.vue +7 -7
  109. package/src/components/form/inputs/PasswordInput.vue +3 -2
  110. package/src/components/form/inputs/RadioGroup.vue +28 -25
  111. package/src/components/form/inputs/RadioPillsInput.vue +12 -12
  112. package/src/components/form/inputs/RangeInput.vue +21 -21
  113. package/src/components/form/inputs/RichText/components/EditorToolbar.vue +107 -92
  114. package/src/components/form/inputs/RichText/components/TableGridSelector.vue +64 -64
  115. package/src/components/form/inputs/RichText/components/gridBox.vue +10 -8
  116. package/src/components/form/inputs/RichText/composables/useCommands.ts +1 -1
  117. package/src/components/form/inputs/RichText/composables/useEditor.ts +12 -12
  118. package/src/components/form/inputs/RichText/composables/useEditorKeyboard.ts +1 -1
  119. package/src/components/form/inputs/RichText/index.vue +138 -138
  120. package/src/components/form/inputs/RichText/utils/commands.ts +84 -85
  121. package/src/components/form/inputs/RichText/utils/debug.ts +1 -1
  122. package/src/components/form/inputs/RichText/utils/formatting.ts +39 -39
  123. package/src/components/form/inputs/RichText/utils/selection.ts +28 -28
  124. package/src/components/form/inputs/RichText/utils/table.ts +19 -19
  125. package/src/components/form/inputs/SelectBtn.vue +1 -1
  126. package/src/components/form/inputs/SelectInput.vue +54 -54
  127. package/src/components/form/inputs/SignaturePad.vue +40 -40
  128. package/src/components/form/inputs/TableField.vue +1 -1
  129. package/src/components/form/inputs/TelInput.vue +54 -53
  130. package/src/components/form/inputs/TextInput.vue +19 -19
  131. package/src/components/form/inputs/ToggleInput.vue +2 -2
  132. package/src/components/form/inputs/Upload/useFileUpload.ts +6 -6
  133. package/src/components/form/useBagelFormState.ts +5 -5
  134. package/src/components/layout/AppLayout.vue +2 -2
  135. package/src/components/layout/AppSidebar.vue +77 -16
  136. package/src/components/layout/Layout.vue +12 -10
  137. package/src/components/layout/SidebarMenu.vue +4 -4
  138. package/src/components/layout/TabbedLayout.vue +17 -17
  139. package/src/components/layout/Tabs.vue +4 -5
  140. package/src/components/layout/TabsNav.vue +14 -14
  141. package/src/components/layout/index.ts +3 -5
  142. package/src/components/lightbox/Lightbox.vue +22 -22
  143. package/src/components/lightbox/index.ts +8 -8
  144. package/src/composables/index.ts +8 -8
  145. package/src/composables/useAddToCalendar.ts +13 -13
  146. package/src/composables/useDevice.ts +2 -2
  147. package/src/composables/useFormField.ts +4 -4
  148. package/src/composables/usePolling.ts +8 -8
  149. package/src/composables/useSchemaField.ts +38 -38
  150. package/src/composables/useTheme.ts +9 -9
  151. package/src/composables/useValidateFieldValue.ts +2 -2
  152. package/src/directives/pattern.ts +25 -25
  153. package/src/directives/ripple.ts +4 -4
  154. package/src/directives/vResize.ts +6 -6
  155. package/src/index.ts +1 -0
  156. package/src/plugins/bagel.ts +4 -4
  157. package/src/plugins/useToast.ts +56 -51
  158. package/src/styles/layout.css +1 -1
  159. package/src/types/index.ts +1 -1
  160. package/src/utils/BagelFormUtils.ts +7 -7
  161. package/src/utils/calendar/Helpers.ts +8 -8
  162. package/src/utils/calendar/dateUtils.ts +22 -22
  163. package/src/utils/calendar/time.ts +25 -25
  164. package/src/utils/calendar/week.ts +25 -25
  165. package/src/utils/elementUtils.ts +27 -27
  166. package/src/utils/sizeParsing.ts +2 -2
  167. package/src/utils/strings.ts +5 -5
  168. package/src/utils/tapDetector.ts +11 -11
  169. package/src/utils/useSearch.ts +29 -29
  170. package/vite.config.ts +0 -2
@@ -1,6 +1,6 @@
1
1
  <script lang="ts" setup>
2
2
  import { useDebounceFn } from '@bagelink/vue'
3
- import { onMounted as vueOnMounted, onUnmounted as vueOnUnmounted, watch as vueWatch } from 'vue'
3
+ import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
4
4
  import TapDetector from '../utils/tapDetector'
5
5
 
6
6
  // Props interface
@@ -9,7 +9,6 @@ interface Props {
9
9
  maxScale?: number
10
10
  zoom?: number
11
11
  resetTrigger?: number
12
- aspectRatio?: number
13
12
  backgroundColor?: string
14
13
  pivot?: string // 'cursor' | 'image-center'
15
14
  zoomingElastic?: boolean
@@ -24,7 +23,6 @@ const {
24
23
  maxScale = 5,
25
24
  zoom,
26
25
  disabled = false,
27
- aspectRatio = 1,
28
26
  backgroundColor = 'transparent',
29
27
  pivot = 'cursor',
30
28
  zoomingElastic = true,
@@ -34,87 +32,84 @@ const {
34
32
  } = defineProps<Props>()
35
33
 
36
34
  const emit = defineEmits(['update:zoom'])
37
- // Reactive state using $ref (vue-macros)
38
- const zoomElement = $ref<HTMLElement | undefined>()
39
- let containerWidth = $ref(1)
40
- let containerHeight = $ref(1)
41
- let containerLeft = $ref(0)
42
- let containerTop = $ref(0)
43
- let translateX = $ref(0)
44
- let animTranslateX = $ref(0)
45
- let translateY = $ref(0)
46
- let animTranslateY = $ref(0)
47
- let _zoom = $ref(zoom ?? 1)
48
- let scale = $computed({
49
- get: () => zoom ?? _zoom,
35
+ // Reactive state using standard Vue composition API
36
+ const zoomElement = ref<HTMLElement | undefined>()
37
+ const containerWidth = ref(1)
38
+ const containerHeight = ref(1)
39
+ const containerLeft = ref(0)
40
+ const containerTop = ref(0)
41
+ const translateX = ref(0)
42
+ const animTranslateX = ref(0)
43
+ const translateY = ref(0)
44
+ const animTranslateY = ref(0)
45
+ const _zoom = ref(zoom ?? 1)
46
+ const scale = computed({
47
+ get: () => zoom ?? _zoom.value,
50
48
  set: (val) => {
51
- _zoom = val
52
- emit('update:zoom', _zoom)
49
+ _zoom.value = val
50
+ emit('update:zoom', _zoom.value)
53
51
  },
54
52
  })
55
53
 
56
- let animScale = $ref(1)
57
- let lastFullWheelTime = $ref(0)
58
- let lastWheelTime = $ref(0)
59
- let lastWheelDirection = $ref<'x' | 'y'>('y')
60
- let isPointerDown = $ref(false)
61
- let pointerPosX = $ref(-1)
62
- let pointerPosY = $ref(-1)
63
- let twoFingerInitDist = $ref(0)
64
- let panLocked = $ref(true)
65
- let raf = $ref<number | undefined>()
66
- let tapDetector = $ref<TapDetector | undefined>()
67
-
68
- let translateXValue = $ref(0)
69
- let translateYValue = $ref(0)
54
+ const animScale = ref(1)
55
+ const lastFullWheelTime = ref(0)
56
+ const lastWheelTime = ref(0)
57
+ const lastWheelDirection = ref<'x' | 'y'>('y')
58
+ const isPointerDown = ref(false)
59
+ const pointerPosX = ref(-1)
60
+ const pointerPosY = ref(-1)
61
+ const twoFingerInitDist = ref(0)
62
+ const panLocked = ref(true)
63
+ const raf = ref<number | undefined>()
64
+ const tapDetector = ref<TapDetector | undefined>()
70
65
 
71
66
  // Momentum/inertia tracking
72
- let velocityX = $ref(0)
73
- let velocityY = $ref(0)
74
- let lastMoveTime = $ref(0)
75
- let momentumRaf = $ref<number | undefined>()
67
+ const velocityX = ref(0)
68
+ const velocityY = ref(0)
69
+ const lastMoveTime = ref(0)
70
+ const momentumRaf = ref<number | undefined>()
76
71
 
77
- const wrapperStyle = $computed(() => {
72
+ const wrapperStyle = computed(() => {
78
73
  // Translation is in normalized coordinates (0.5 = half container)
79
74
  // Convert to pixels
80
- translateXValue = containerWidth * animTranslateX
81
- translateYValue = containerHeight * animTranslateY
75
+ const translateXValue = containerWidth.value * animTranslateX.value
76
+ const translateYValue = containerHeight.value * animTranslateY.value
82
77
  return {
83
78
  transform: [
84
79
  `translate(${translateXValue}px, ${translateYValue}px)`,
85
- `scale(${animScale})`,
80
+ `scale(${animScale.value})`,
86
81
  ].join(' '),
87
82
  transformOrigin: '50% 50%',
88
83
  }
89
84
  })
90
85
 
91
- vueWatch(() => scale, (newScale) => {
86
+ watch(() => scale.value, (newScale) => {
92
87
  const { x, y } = calcTranslateLimit()
93
- translateX = Math.max(-x, Math.min(x, translateX))
94
- translateY = Math.max(-y, Math.min(y, translateY))
88
+ translateX.value = Math.max(-x, Math.min(x, translateX.value))
89
+ translateY.value = Math.max(-y, Math.min(y, translateY.value))
95
90
  if (newScale !== 1) {
96
- panLocked = false
91
+ panLocked.value = false
97
92
  }
98
93
  })
99
94
 
100
95
  function reset() {
101
- scale = 1
102
- panLocked = true
103
- translateX = 0
104
- translateY = 0
96
+ scale.value = 1
97
+ panLocked.value = true
98
+ translateX.value = 0
99
+ translateY.value = 0
105
100
  }
106
101
 
107
102
  defineExpose({ reset })
108
103
 
109
104
  function tryToScale(scaleDelta: number) {
110
105
  if (disabled) { return }
111
- let newScale = scale * scaleDelta
106
+ let newScale = scale.value * scaleDelta
112
107
  if (zoomingElastic) {
113
108
  if (newScale < minScale || newScale > maxScale) {
114
109
  let log = Math.log2(scaleDelta)
115
110
  log *= 0.2
116
111
  scaleDelta = 2 ** log
117
- newScale = scale * scaleDelta
112
+ newScale = scale.value * scaleDelta
118
113
  }
119
114
  } else {
120
115
  if (newScale < minScale) {
@@ -123,104 +118,104 @@ function tryToScale(scaleDelta: number) {
123
118
  newScale = maxScale
124
119
  }
125
120
  }
126
- scaleDelta = newScale / scale
127
- scale = newScale
121
+ scaleDelta = newScale / scale.value
122
+ scale.value = newScale
128
123
  if (pivot !== 'image-center') {
129
- const normMousePosX = (pointerPosX - containerLeft) / containerWidth
130
- const normMousePosY = (pointerPosY - containerTop) / containerHeight
131
- translateX = (0.5 + translateX - normMousePosX) * scaleDelta + normMousePosX - 0.5
132
- translateY = (0.5 + translateY - normMousePosY) * scaleDelta + normMousePosY - 0.5
124
+ const normMousePosX = (pointerPosX.value - containerLeft.value) / containerWidth.value
125
+ const normMousePosY = (pointerPosY.value - containerTop.value) / containerHeight.value
126
+ translateX.value = (0.5 + translateX.value - normMousePosX) * scaleDelta + normMousePosX - 0.5
127
+ translateY.value = (0.5 + translateY.value - normMousePosY) * scaleDelta + normMousePosY - 0.5
133
128
  }
134
129
  }
135
130
 
136
131
  function setPointerPosCenter() {
137
- pointerPosX = containerLeft + containerWidth / 2
138
- pointerPosY = containerTop + containerHeight / 2
132
+ pointerPosX.value = containerLeft.value + containerWidth.value / 2
133
+ pointerPosY.value = containerTop.value + containerHeight.value / 2
139
134
  }
140
135
 
141
136
  function onPointerMove(newMousePosX: number, newMousePosY: number) {
142
- if (isPointerDown) {
137
+ if (isPointerDown.value) {
143
138
  const currentTime = Date.now()
144
- const pixelDeltaX = newMousePosX - pointerPosX
145
- const pixelDeltaY = newMousePosY - pointerPosY
139
+ const pixelDeltaX = newMousePosX - pointerPosX.value
140
+ const pixelDeltaY = newMousePosY - pointerPosY.value
146
141
 
147
- if (!panLocked) {
142
+ if (!panLocked.value) {
148
143
  // Calculate velocity for momentum
149
- const timeDelta = currentTime - lastMoveTime
144
+ const timeDelta = currentTime - lastMoveTime.value
150
145
  if (timeDelta > 0) {
151
- velocityX = pixelDeltaX / timeDelta
152
- velocityY = pixelDeltaY / timeDelta
146
+ velocityX.value = pixelDeltaX / timeDelta
147
+ velocityY.value = pixelDeltaY / timeDelta
153
148
  }
154
149
 
155
150
  const translateLimit = calcTranslateLimit()
156
151
  const maxTranslateX = translateLimit.x
157
152
  const maxTranslateY = translateLimit.y
158
- const newTranslateX = translateX + pixelDeltaX / containerWidth
159
- const newTranslateY = translateY + pixelDeltaY / containerHeight
153
+ const newTranslateX = translateX.value + pixelDeltaX / containerWidth.value
154
+ const newTranslateY = translateY.value + pixelDeltaY / containerHeight.value
160
155
 
161
- translateX = Math.max(-maxTranslateX, Math.min(maxTranslateX, newTranslateX))
162
- translateY = Math.max(-maxTranslateY, Math.min(maxTranslateY, newTranslateY))
156
+ translateX.value = Math.max(-maxTranslateX, Math.min(maxTranslateX, newTranslateX))
157
+ translateY.value = Math.max(-maxTranslateY, Math.min(maxTranslateY, newTranslateY))
163
158
 
164
- lastMoveTime = currentTime
159
+ lastMoveTime.value = currentTime
165
160
  }
166
161
  }
167
- pointerPosX = newMousePosX
168
- pointerPosY = newMousePosY
162
+ pointerPosX.value = newMousePosX
163
+ pointerPosY.value = newMousePosY
169
164
  }
170
165
 
171
166
  function applyMomentum() {
172
- if (Math.abs(velocityX) < 0.01 && Math.abs(velocityY) < 0.01) {
173
- velocityX = 0
174
- velocityY = 0
175
- if (momentumRaf) {
176
- cancelAnimationFrame(momentumRaf)
177
- momentumRaf = undefined
167
+ if (Math.abs(velocityX.value) < 0.01 && Math.abs(velocityY.value) < 0.01) {
168
+ velocityX.value = 0
169
+ velocityY.value = 0
170
+ if (momentumRaf.value) {
171
+ cancelAnimationFrame(momentumRaf.value)
172
+ momentumRaf.value = undefined
178
173
  }
179
174
  return
180
175
  }
181
176
 
182
177
  const translateLimit = calcTranslateLimit()
183
- const newTranslateX = translateX + velocityX * 16 / containerWidth
184
- const newTranslateY = translateY + velocityY * 16 / containerHeight
178
+ const newTranslateX = translateX.value + velocityX.value * 16 / containerWidth.value
179
+ const newTranslateY = translateY.value + velocityY.value * 16 / containerHeight.value
185
180
 
186
- translateX = Math.max(-translateLimit.x, Math.min(translateLimit.x, newTranslateX))
187
- translateY = Math.max(-translateLimit.y, Math.min(translateLimit.y, newTranslateY))
181
+ translateX.value = Math.max(-translateLimit.x, Math.min(translateLimit.x, newTranslateX))
182
+ translateY.value = Math.max(-translateLimit.y, Math.min(translateLimit.y, newTranslateY))
188
183
 
189
184
  // Apply friction
190
- velocityX *= 0.95
191
- velocityY *= 0.95
185
+ velocityX.value *= 0.95
186
+ velocityY.value *= 0.95
192
187
 
193
- momentumRaf = requestAnimationFrame(applyMomentum)
188
+ momentumRaf.value = requestAnimationFrame(applyMomentum)
194
189
  }
195
190
 
196
191
  const onInteractionEnd = useDebounceFn(() => {
197
192
  limit()
198
- panLocked = scale === 1
193
+ panLocked.value = scale.value === 1
199
194
 
200
195
  // Start momentum animation if there's significant velocity
201
- if (!panLocked && (Math.abs(velocityX) > 0.1 || Math.abs(velocityY) > 0.1)) {
202
- if (momentumRaf) cancelAnimationFrame(momentumRaf)
196
+ if (!panLocked.value && (Math.abs(velocityX.value) > 0.1 || Math.abs(velocityY.value) > 0.1)) {
197
+ if (momentumRaf.value) cancelAnimationFrame(momentumRaf.value)
203
198
  applyMomentum()
204
199
  } else {
205
- velocityX = 0
206
- velocityY = 0
200
+ velocityX.value = 0
201
+ velocityY.value = 0
207
202
  }
208
203
  }, 50)
209
204
 
210
205
  function limit() {
211
- if (scale < minScale) {
212
- scale = minScale
213
- } else if (scale > maxScale) {
214
- tryToScale(maxScale / scale)
206
+ if (scale.value < minScale) {
207
+ scale.value = minScale
208
+ } else if (scale.value > maxScale) {
209
+ tryToScale(maxScale / scale.value)
215
210
  }
216
211
 
217
212
  if (limitTranslation) {
218
213
  const translateLimit = calcTranslateLimit()
219
- if (Math.abs(translateX) > translateLimit.x) {
220
- translateX *= translateLimit.x / Math.abs(translateX)
214
+ if (Math.abs(translateX.value) > translateLimit.x) {
215
+ translateX.value *= translateLimit.x / Math.abs(translateX.value)
221
216
  }
222
- if (Math.abs(translateY) > translateLimit.y) {
223
- translateY *= translateLimit.y / Math.abs(translateY)
217
+ if (Math.abs(translateY.value) > translateLimit.y) {
218
+ translateY.value *= translateLimit.y / Math.abs(translateY.value)
224
219
  }
225
220
  }
226
221
  }
@@ -238,7 +233,7 @@ function calcTranslateLimit() {
238
233
  // Max pan distance in normalized coords = (scale - 1) / 2
239
234
  // This works for both X and Y directions regardless of aspect ratio
240
235
 
241
- const basePanLimit = Math.max(0, (scale - 1) / 2)
236
+ const basePanLimit = Math.max(0, (scale.value - 1) / 2)
242
237
 
243
238
  return {
244
239
  x: basePanLimit,
@@ -251,18 +246,18 @@ function onMouseWheel(ev: WheelEvent) {
251
246
  ev.preventDefault()
252
247
  const currTime = Date.now()
253
248
  if (Math.abs(ev.deltaY) === 120) {
254
- if (currTime - lastFullWheelTime > 50) {
249
+ if (currTime - lastFullWheelTime.value > 50) {
255
250
  onMouseWheelDo(ev.deltaY)
256
- lastFullWheelTime = currTime
251
+ lastFullWheelTime.value = currTime
257
252
  }
258
253
  } else {
259
- if (currTime - lastWheelTime > 50) {
260
- lastWheelDirection = ev.deltaX > ev.deltaY ? 'x' : 'y'
261
- if (lastWheelDirection === 'y') {
254
+ if (currTime - lastWheelTime.value > 50) {
255
+ lastWheelDirection.value = ev.deltaX > ev.deltaY ? 'x' : 'y'
256
+ if (lastWheelDirection.value === 'y') {
262
257
  onMouseWheelDo(ev.deltaY)
263
258
  }
264
259
  }
265
- lastWheelTime = currTime
260
+ lastWheelTime.value = currTime
266
261
  }
267
262
  }
268
263
 
@@ -275,22 +270,22 @@ function onMouseWheelDo(wheelDelta: number) {
275
270
 
276
271
  function onMouseDown(ev: MouseEvent) {
277
272
  refreshContainerPos()
278
- isPointerDown = true
279
- pointerPosX = ev.clientX
280
- pointerPosY = ev.clientY
281
- lastMoveTime = Date.now()
282
- velocityX = 0
283
- velocityY = 0
284
- if (momentumRaf) {
285
- cancelAnimationFrame(momentumRaf)
286
- momentumRaf = undefined
273
+ isPointerDown.value = true
274
+ pointerPosX.value = ev.clientX
275
+ pointerPosY.value = ev.clientY
276
+ lastMoveTime.value = Date.now()
277
+ velocityX.value = 0
278
+ velocityY.value = 0
279
+ if (momentumRaf.value) {
280
+ cancelAnimationFrame(momentumRaf.value)
281
+ momentumRaf.value = undefined
287
282
  }
288
283
  document.addEventListener('mousemove', onMouseMove)
289
284
  document.addEventListener('mouseup', onMouseUp)
290
285
  }
291
286
 
292
287
  function onMouseUp() {
293
- isPointerDown = false
288
+ isPointerDown.value = false
294
289
  onInteractionEnd()
295
290
  document.removeEventListener('mouseup', onMouseUp)
296
291
  document.removeEventListener('mousemove', onMouseMove)
@@ -298,7 +293,7 @@ function onMouseUp() {
298
293
 
299
294
  function onMouseMove(ev: MouseEvent) {
300
295
  // Prevent swiper from handling mouse drag when panning zoomed image
301
- if (!panLocked && scale > 1) {
296
+ if (!panLocked.value && scale.value > 1) {
302
297
  ev.stopPropagation()
303
298
  }
304
299
  onPointerMove(ev.clientX, ev.clientY)
@@ -307,41 +302,41 @@ function onMouseMove(ev: MouseEvent) {
307
302
  function onTouchStart(ev: TouchEvent) {
308
303
  if (ev.touches.length === 1) {
309
304
  refreshContainerPos()
310
- pointerPosX = ev.touches[0].clientX
311
- pointerPosY = ev.touches[0].clientY
312
- lastMoveTime = Date.now()
313
- velocityX = 0
314
- velocityY = 0
315
- if (momentumRaf) {
316
- cancelAnimationFrame(momentumRaf)
317
- momentumRaf = undefined
305
+ pointerPosX.value = ev.touches[0].clientX
306
+ pointerPosY.value = ev.touches[0].clientY
307
+ lastMoveTime.value = Date.now()
308
+ velocityX.value = 0
309
+ velocityY.value = 0
310
+ if (momentumRaf.value) {
311
+ cancelAnimationFrame(momentumRaf.value)
312
+ momentumRaf.value = undefined
318
313
  }
319
- isPointerDown = true
314
+ isPointerDown.value = true
320
315
  } else if (ev.touches.length === 2) {
321
- if (momentumRaf) {
322
- cancelAnimationFrame(momentumRaf)
323
- momentumRaf = undefined
316
+ if (momentumRaf.value) {
317
+ cancelAnimationFrame(momentumRaf.value)
318
+ momentumRaf.value = undefined
324
319
  }
325
- velocityX = 0
326
- velocityY = 0
327
- isPointerDown = true
328
- pointerPosX = (ev.touches[0].clientX + ev.touches[1].clientX) / 2
329
- pointerPosY = (ev.touches[0].clientY + ev.touches[1].clientY) / 2
320
+ velocityX.value = 0
321
+ velocityY.value = 0
322
+ isPointerDown.value = true
323
+ pointerPosX.value = (ev.touches[0].clientX + ev.touches[1].clientX) / 2
324
+ pointerPosY.value = (ev.touches[0].clientY + ev.touches[1].clientY) / 2
330
325
  const distX = ev.touches[0].clientX - ev.touches[1].clientX
331
326
  const distY = ev.touches[0].clientY - ev.touches[1].clientY
332
- twoFingerInitDist = Math.sqrt(distX * distX + distY * distY)
327
+ twoFingerInitDist.value = Math.sqrt(distX * distX + distY * distY)
333
328
  }
334
329
  document.addEventListener('touchend', onTouchEnd)
335
330
  }
336
331
 
337
332
  function onTouchEnd(ev: TouchEvent) {
338
333
  if (ev.touches.length === 0) {
339
- isPointerDown = false
340
- if (Math.abs(scale - 1) < 0.1) { scale = 1 }
334
+ isPointerDown.value = false
335
+ if (Math.abs(scale.value - 1) < 0.1) { scale.value = 1 }
341
336
  onInteractionEnd()
342
337
  } else if (ev.touches.length === 1) {
343
- pointerPosX = ev.touches[0].clientX
344
- pointerPosY = ev.touches[0].clientY
338
+ pointerPosX.value = ev.touches[0].clientX
339
+ pointerPosY.value = ev.touches[0].clientY
345
340
  }
346
341
  document.removeEventListener('touchend', onTouchEnd)
347
342
  }
@@ -349,7 +344,7 @@ function onTouchEnd(ev: TouchEvent) {
349
344
  function onTouchMove(ev: TouchEvent) {
350
345
  if (ev.touches.length === 1) {
351
346
  // Prevent swiper from handling touch when panning zoomed image
352
- if (!panLocked && scale > 1) {
347
+ if (!panLocked.value && scale.value > 1) {
353
348
  ev.stopPropagation()
354
349
  }
355
350
  onPointerMove(ev.touches[0].clientX, ev.touches[0].clientY)
@@ -359,24 +354,24 @@ function onTouchMove(ev: TouchEvent) {
359
354
  const distX = ev.touches[0].clientX - ev.touches[1].clientX
360
355
  const distY = ev.touches[0].clientY - ev.touches[1].clientY
361
356
  const newTwoFingerDist = Math.sqrt(distX * distX + distY * distY)
362
- tryToScale(newTwoFingerDist / twoFingerInitDist)
363
- twoFingerInitDist = newTwoFingerDist
357
+ tryToScale(newTwoFingerDist / twoFingerInitDist.value)
358
+ twoFingerInitDist.value = newTwoFingerDist
364
359
  }
365
360
  }
366
361
 
367
362
  function refreshContainerPos() {
368
- if (zoomElement) {
369
- const rect = zoomElement.getBoundingClientRect()
370
- containerLeft = rect.left
371
- containerTop = rect.top
363
+ if (zoomElement.value) {
364
+ const rect = zoomElement.value.getBoundingClientRect()
365
+ containerLeft.value = rect.left
366
+ containerTop.value = rect.top
372
367
  }
373
368
  }
374
369
 
375
370
  function loop() {
376
- animScale = gainOn(animScale, scale)
377
- animTranslateX = gainOn(animTranslateX, translateX)
378
- animTranslateY = gainOn(animTranslateY, translateY)
379
- raf = window.requestAnimationFrame(loop)
371
+ animScale.value = gainOn(animScale.value, scale.value)
372
+ animTranslateX.value = gainOn(animTranslateX.value, translateX.value)
373
+ animTranslateY.value = gainOn(animTranslateY.value, translateY.value)
374
+ raf.value = window.requestAnimationFrame(loop)
380
375
  }
381
376
 
382
377
  function gainOn(from: number, to: number) {
@@ -386,14 +381,14 @@ function gainOn(from: number, to: number) {
386
381
  }
387
382
 
388
383
  // Lifecycle hooks
389
- vueOnMounted(() => {
390
- tapDetector = new TapDetector()
391
- if (zoomElement) { tapDetector.attach(zoomElement) }
384
+ onMounted(() => {
385
+ tapDetector.value = new TapDetector()
386
+ if (zoomElement.value) { tapDetector.value.attach(zoomElement.value) }
392
387
  if (doubleClickToZoom) {
393
- tapDetector.onDoubleTap(onDoubleTap as any)
388
+ tapDetector.value.onDoubleTap(onDoubleTap as any)
394
389
  // Also add native dblclick event for mouse
395
- if (zoomElement) {
396
- zoomElement.addEventListener('dblclick', onDoubleTap as any)
390
+ if (zoomElement.value) {
391
+ zoomElement.value.addEventListener('dblclick', onDoubleTap as any)
397
392
  }
398
393
  }
399
394
  window.addEventListener('resize', onWindowResize)
@@ -402,23 +397,23 @@ vueOnMounted(() => {
402
397
  loop()
403
398
  })
404
399
 
405
- vueOnUnmounted(() => {
406
- if (zoomElement) {
407
- tapDetector?.detach(zoomElement)
400
+ onUnmounted(() => {
401
+ if (zoomElement.value) {
402
+ tapDetector.value?.detach(zoomElement.value)
408
403
  if (doubleClickToZoom) {
409
- zoomElement.removeEventListener('dblclick', onDoubleTap as any)
404
+ zoomElement.value.removeEventListener('dblclick', onDoubleTap as any)
410
405
  }
411
406
  }
412
407
  window.removeEventListener('resize', onWindowResize)
413
- if (raf) { window.cancelAnimationFrame(raf) }
414
- if (momentumRaf) { window.cancelAnimationFrame(momentumRaf) }
408
+ if (raf.value) { window.cancelAnimationFrame(raf.value) }
409
+ if (momentumRaf.value) { window.cancelAnimationFrame(momentumRaf.value) }
415
410
  })
416
411
 
417
412
  function onDoubleTap(ev: MouseEvent) {
418
413
  // Update pointer position if available
419
414
  if (ev.clientX > 0) {
420
- pointerPosX = ev.clientX
421
- pointerPosY = ev.clientY
415
+ pointerPosX.value = ev.clientX
416
+ pointerPosY.value = ev.clientY
422
417
  }
423
418
 
424
419
  // Calculate zoom levels
@@ -426,12 +421,12 @@ function onDoubleTap(ev: MouseEvent) {
426
421
  const highZoom = maxScale
427
422
 
428
423
  // Cycle through three states: 1x -> medium -> max -> 1x
429
- if (scale === 1) {
424
+ if (scale.value === 1) {
430
425
  // From no zoom -> medium zoom
431
426
  tryToScale(mediumZoom)
432
- } else if (scale < highZoom - 0.1) {
427
+ } else if (scale.value < highZoom - 0.1) {
433
428
  // From medium zoom -> max zoom
434
- tryToScale(highZoom / scale)
429
+ tryToScale(highZoom / scale.value)
435
430
  } else {
436
431
  // From max zoom -> no zoom (reset)
437
432
  reset()
@@ -439,10 +434,10 @@ function onDoubleTap(ev: MouseEvent) {
439
434
  }
440
435
 
441
436
  function onWindowResize() {
442
- if (zoomElement) {
443
- const styles = window.getComputedStyle(zoomElement)
444
- containerWidth = Number.parseFloat(styles.width)
445
- containerHeight = Number.parseFloat(styles.height)
437
+ if (zoomElement.value) {
438
+ const styles = window.getComputedStyle(zoomElement.value)
439
+ containerWidth.value = Number.parseFloat(styles.width)
440
+ containerHeight.value = Number.parseFloat(styles.height)
446
441
  setPointerPosCenter()
447
442
  limit()
448
443
  }
@@ -57,7 +57,7 @@ const observer = ref<IntersectionObserver | null>(null)
57
57
  const chartRef = ref<HTMLElement | null>(null)
58
58
 
59
59
  const chartData = computed(() => {
60
- if (!props.data || 0 === props.data.length) {return []}
60
+ if (!props.data || props.data.length === 0) { return [] }
61
61
 
62
62
  // Use all data without limiting to maxBars
63
63
  const maxValue = Math.max(...props.data.map(d => d.value), 1)
@@ -71,8 +71,8 @@ const chartData = computed(() => {
71
71
  // Animation computed properties
72
72
  const getBarOpacity = computed(() => {
73
73
  return (index: number) => {
74
- if (!props.animated) {return 1}
75
- if (!isInView.value) {return 0}
74
+ if (!props.animated) { return 1 }
75
+ if (!isInView.value) { return 0 }
76
76
 
77
77
  const totalBars = chartData.value.length
78
78
 
@@ -90,7 +90,7 @@ function easeOutCubic(t: number): number {
90
90
  }
91
91
 
92
92
  function startAnimation() {
93
- if (isAnimating.value || !props.animated) {return}
93
+ if (isAnimating.value || !props.animated) { return }
94
94
 
95
95
  console.log(`🎯 TrendChart: Starting animation with ${props.animationDuration}ms duration`)
96
96
  isAnimating.value = true
@@ -105,7 +105,7 @@ function startAnimation() {
105
105
 
106
106
  animatedProgress.value = easedProgress
107
107
 
108
- if (1 > progress) {
108
+ if (progress < 1) {
109
109
  requestAnimationFrame(animate)
110
110
  } else {
111
111
  isAnimating.value = false
@@ -117,7 +117,7 @@ function startAnimation() {
117
117
  }
118
118
 
119
119
  function setupIntersectionObserver() {
120
- if (!chartRef.value || observer.value) {return}
120
+ if (!chartRef.value || observer.value) { return }
121
121
 
122
122
  observer.value = new IntersectionObserver(
123
123
  (entries) => {
@@ -27,10 +27,10 @@ const props = withDefaults(defineProps<Props>(), {
27
27
  subtitle: ''
28
28
  })
29
29
 
30
- const isIncreasing = computed(() => 0 <= props.percentageChange)
30
+ const isIncreasing = computed(() => props.percentageChange >= 0)
31
31
 
32
32
  const formattedValue = computed(() => {
33
- if ('string' === typeof props.value) {return props.value}
33
+ if (typeof props.value === 'string') { return props.value }
34
34
 
35
35
  if (props.currency) {
36
36
  return new Intl.NumberFormat('he-IL', {