@bagelink/vue 1.12.61 → 1.12.67

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.12.61",
4
+ "version": "1.12.67",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -4,7 +4,7 @@ import type { SetupContext } from 'vue'
4
4
  import { Icon, Loading, useModal, useI18n, resolveI18n } from '@bagelink/vue'
5
5
  import { useSlots, ref, onMounted, onUnmounted, computed } from 'vue'
6
6
  import { RouterLink } from 'vue-router'
7
-
7
+ defineOptions({ name: 'BglBtn' })
8
8
  const props = withDefaults(
9
9
  defineProps<{
10
10
  disabled?: boolean
@@ -23,7 +23,7 @@ const props = withDefaults(
23
23
  loading?: boolean
24
24
  role?: string
25
25
  value?: TranslatableString
26
- to?: string
26
+ to?: string | Record<string, any>
27
27
  href?: string
28
28
  round?: boolean
29
29
  is?: string
@@ -58,15 +58,16 @@ defineExpose({ contentWindow })
58
58
  ref="iframe"
59
59
  :src
60
60
  :title
61
- frameborder="none"
62
- :width
63
- :height
61
+ frameborder="0"
62
+ :width="width ?? '100%'"
63
+ :height="height ?? '100%'"
64
64
  allowpaymentrequest="true"
65
65
  :marginwidth
66
66
  :marginheight
67
67
  :csp
68
68
  :scrolling
69
69
  :srcset
70
+ style="display:block; border:none;"
70
71
  @load="$event => emit('load', $event)"
71
72
  />
72
73
  </template>
@@ -43,8 +43,13 @@ defineProps<{ items: NavLink[] }>()
43
43
  </template>
44
44
 
45
45
  <style scoped>
46
- .bgl_btn.router-link-active {
46
+ /* .bgl_btn.router-link-active {
47
47
  background-color: var(--bgl-gray-40);
48
+ } */
49
+
50
+ .bglTopMenu .router-link-active {
51
+ background: var(--bgl-primary) !important;
52
+ color: var(--bgl-white) !important;
48
53
  }
49
54
  </style>
50
55
 
@@ -714,7 +714,7 @@ onUnmounted(() => {
714
714
  backgroundColor: event.color || 'var(--bgl-primary)',
715
715
  }" @mousedown.stop @click.stop="handleEventSelection(event, $event)"
716
716
  >
717
- <div class="overflow-hidden color-white p-025 txt12 h-100p">
717
+ <div class="overflow-hidden color-white p-025 txt12 h-100p flex gap-1 flex-wrap">
718
718
  <div class="white-space ellipsis-1">
719
719
  {{ event.title }}
720
720
  </div>
@@ -5,7 +5,7 @@ import { inject, computed } from 'vue'
5
5
  interface Props {
6
6
  title?: string
7
7
  showMenuButton?: boolean
8
- backTo?: string
8
+ backTo?: string | Record<string, any>
9
9
  border?: boolean
10
10
  }
11
11
 
@@ -22,6 +22,7 @@ const props = defineProps<{
22
22
  fullWidthMobile?: boolean
23
23
  alignTxt?: 'center' | 'start' | 'end'
24
24
  alignTxtMobile?: 'center' | 'start' | 'end'
25
+ outline?: boolean
25
26
  }>()
26
27
 
27
28
  const emit = defineEmits(['update:modelValue'])
@@ -34,21 +35,40 @@ currentTab.value
34
35
  const tabsWrap = ref<HTMLElement | undefined>(undefined)
35
36
  const tabEls = ref<HTMLElement[]>([])
36
37
 
38
+ let resizeObserver: ResizeObserver | undefined
39
+
40
+ /** Position relative to tabs wrap content box (works after breakpoint / font / scroll changes). */
41
+ function measureActiveTabIndicator(wrap: HTMLElement, activeTab: HTMLElement) {
42
+ const wrapRect = wrap.getBoundingClientRect()
43
+ const tabRect = activeTab.getBoundingClientRect()
44
+ const left = tabRect.left - wrapRect.left + wrap.scrollLeft
45
+ const width = tabRect.width
46
+ if (width > 0) {
47
+ wrap.style.setProperty('--indicator-left', `${left}px`)
48
+ wrap.style.setProperty('--indicator-width', `${width}px`)
49
+ wrap.style.setProperty('--indicator-opacity', '1')
50
+ }
51
+ }
52
+
37
53
  function updateIndicator() {
38
54
  nextTick(() => {
39
- if (!tabsWrap.value) { return }
40
- const activeTab = tabEls.value.find(tab => tab.classList.contains('active'))
41
- if (activeTab) {
42
- // Wait a bit more to ensure CSS is fully loaded and elements are properly sized
43
- setTimeout(() => {
44
- const { offsetLeft, offsetWidth } = activeTab
45
- if (offsetLeft >= 0 && offsetWidth > 0) { // Ensure valid measurements
46
- tabsWrap.value?.style.setProperty('--indicator-left', `${offsetLeft}px`)
47
- tabsWrap.value?.style.setProperty('--indicator-width', `${offsetWidth}px`)
48
- tabsWrap.value?.style.setProperty('--indicator-opacity', '1')
49
- }
50
- }, 10)
55
+ const wrap = tabsWrap.value
56
+ if (!wrap) { return }
57
+
58
+ const apply = () => {
59
+ tabEls.value = Array.from(wrap.querySelectorAll<HTMLElement>('.bgl_tab'))
60
+ const activeTab = tabEls.value.find(tab => tab.classList.contains('active'))
61
+ if (!activeTab) {
62
+ wrap.style.setProperty('--indicator-opacity', '0')
63
+ return
64
+ }
65
+ measureActiveTabIndicator(wrap, activeTab)
51
66
  }
67
+
68
+ // Double rAF: layout + media-query / font metrics often settle after one frame (e.g. mobile ↔ desktop).
69
+ requestAnimationFrame(() => {
70
+ requestAnimationFrame(apply)
71
+ })
52
72
  })
53
73
  }
54
74
 
@@ -80,32 +100,51 @@ watch(
80
100
  onMounted(() => {
81
101
  tabEls.value = Array.from(tabsWrap.value?.querySelectorAll('.bgl_tab') || [])
82
102
 
83
- // Wait for the next frame to ensure all CSS and layout calculations are done
84
103
  requestAnimationFrame(() => {
85
104
  updateIndicator()
86
105
  })
87
106
 
88
107
  window.addEventListener('resize', updateIndicator)
108
+ tabsWrap.value?.addEventListener('scroll', updateIndicator, { passive: true })
109
+
110
+ if (typeof ResizeObserver !== 'undefined' && tabsWrap.value) {
111
+ resizeObserver = new ResizeObserver(() => {
112
+ updateIndicator()
113
+ })
114
+ resizeObserver.observe(tabsWrap.value)
115
+ }
116
+
117
+ if (typeof window !== 'undefined' && window.visualViewport) {
118
+ // Mobile browser chrome / zoom — window "resize" alone can miss this.
119
+ window.visualViewport.addEventListener('resize', updateIndicator)
120
+ }
89
121
  })
90
122
 
91
123
  watch(
92
- () => tabEls.value,
124
+ () => props.tabs,
93
125
  () => {
94
126
  nextTick(() => { updateIndicator() })
95
127
  },
96
128
  { deep: true }
97
129
  )
130
+
98
131
  onBeforeUnmount(() => {
99
132
  window.removeEventListener('resize', updateIndicator)
133
+ tabsWrap.value?.removeEventListener('scroll', updateIndicator)
134
+ resizeObserver?.disconnect()
135
+ resizeObserver = undefined
136
+ if (typeof window !== 'undefined' && window.visualViewport) {
137
+ window.visualViewport.removeEventListener('resize', updateIndicator)
138
+ }
100
139
  })
101
140
  </script>
102
141
 
103
142
  <template>
104
- <div ref="tabsWrap" class="grid auto-flow-columns relative fit-content bgl_tabs_wrap overflow-hidden" :class="{ 'bgl_flat-tabs': flat, 'bgl_vertical-tabs': vertical }">
143
+ <div ref="tabsWrap" class="grid auto-flow-columns relative fit-content bgl_tabs_wrap overflow-hidden" :class="{ 'bgl_flat-tabs': flat, 'bgl_vertical-tabs': vertical, 'outline': outline }">
105
144
  <slot name="tabs" v-bind="{ selectTab, isActive, tabLabel, tabs: tabEls }">
106
145
  <button v-for="(tab, i) in props.tabs" :key="i" type="button" :class="[
107
146
  { active: isActive(tab) },
108
- {
147
+ {
109
148
  'bgl_tab-thin': thin,
110
149
  'bgl_tab-xs': size === 'xs' || size === 'extra-small',
111
150
  'bgl_tab-s': size === 's' || size === 'small',