@bagelink/vue 1.12.47 → 1.12.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.
@@ -1 +1 @@
1
- {"version":3,"file":"dateUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/calendar/dateUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAG7G,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;AACtF,YAAY,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEjF,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAkD1D,wBAAgB,OAAO,CACtB,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,YAAY,CAAC,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;CAAE,UA4DnF"}
1
+ {"version":3,"file":"dateUtils.d.ts","sourceRoot":"","sources":["../../../src/utils/calendar/dateUtils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAG7G,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;AACtF,YAAY,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AAEjF,KAAK,WAAW,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AA6D1D,wBAAgB,OAAO,CACtB,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,YAAY,CAAC,EAAE,WAAW,GAAG;IAAE,IAAI,CAAC,EAAE,WAAW,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;CAAE,UAiEnF"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/vue",
3
3
  "type": "module",
4
- "version": "1.12.47",
4
+ "version": "1.12.51",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -13,6 +13,9 @@ export type TriggerEvent = 'click' | 'hover'
13
13
 
14
14
  defineOptions({ inheritAttrs: false, name: 'DropDown' })
15
15
 
16
+ // Module-level counter so each Dropdown instance gets a unique id
17
+ let _bglIdCounter = 0
18
+
16
19
  const props = withDefaults(defineProps<{
17
20
  value?: string
18
21
  thin?: boolean
@@ -59,6 +62,9 @@ const shown = defineModel('shown', { type: Boolean, default: false })
59
62
 
60
63
  const triggerWrapRef = ref<HTMLElement | null>(null)
61
64
  const popoverRef = ref<HTMLElement | null>(null)
65
+
66
+ // Unique id for this popover instance, used to track parent–child relationships across teleported popovers
67
+ const bglId = `bgl-dd-${++_bglIdCounter}`
62
68
  const teleportTarget = ref<string | Element>('body')
63
69
 
64
70
  const { isMobile, innerWidth } = useDevice()
@@ -135,6 +141,14 @@ async function internalShow() {
135
141
  // Wait for Teleport to move the element to the new target before promoting to top layer
136
142
  await nextTick()
137
143
  if (!popoverRef.value) return
144
+
145
+ // Tag with our own id and, if the trigger lives inside another open popover, tag with that owner's id.
146
+ // This lets ancestor Dropdowns skip closing when a click lands inside our (teleported) popover.
147
+ popoverRef.value.dataset.bglId = bglId
148
+ const ownerPopover = triggerWrapRef.value?.closest<HTMLElement>('[data-bgl-id]')
149
+ if (ownerPopover?.dataset.bglId) popoverRef.value.dataset.bglOwner = ownerPopover.dataset.bglId
150
+ else delete popoverRef.value.dataset.bglOwner
151
+
138
152
  // Show hidden first so floating-ui can measure it, then position, then reveal
139
153
  popoverRef.value.style.opacity = '0'
140
154
  popoverRef.value.showPopover()
@@ -180,6 +194,15 @@ function onDocumentPointerDown(e: PointerEvent) {
180
194
  if (!props.autoHide || !isOpen()) return
181
195
  const target = e.target as Node
182
196
  if (popoverRef.value?.contains(target) || triggerWrapRef.value?.contains(target)) return
197
+ // Don't close if the click landed inside a descendant popover (e.g. a SelectInput inside this
198
+ // dropdown that teleports its popup to <body>). We detect this via a data-bgl-owner attribute
199
+ // that each Dropdown sets on its popover element to point to the nearest ancestor popover's id.
200
+ const openPopovers = document.querySelectorAll<HTMLElement>('[popover]:popover-open')
201
+ const myId = popoverRef.value?.dataset.bglId
202
+ for (const p of openPopovers) {
203
+ if (p === popoverRef.value) continue
204
+ if (p.contains(target) && myId && p.dataset.bglOwner === myId) return
205
+ }
183
206
  internalHide()
184
207
  }
185
208
 
@@ -290,7 +290,6 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
290
290
  <Dropdown
291
291
  flat placement="bottom-end" icon="filter_alt"
292
292
  :value="activeFiltersCount > 0 ? `${currentTexts.filter} (${activeFiltersCount})` : currentTexts.filter" thin
293
- :auto-hide="false"
294
293
  >
295
294
  <div class="p-1 m_p-05">
296
295
  <div class="p-025 bg-bg radius-1 mb-05 m_max-h-300px m_overflow m_border">
@@ -23,6 +23,7 @@ body>div ::-webkit-scrollbar-corner {
23
23
  .bgl-scrollbar-bordered::-webkit-scrollbar-track,
24
24
  .scrollbar-border::-webkit-scrollbar-track {
25
25
  border-inline-start: 1px solid rgba(0, 0, 0, .08) !important;
26
+ margin-block: 0 !important;
26
27
  }
27
28
 
28
29
  .hide-scrollbar::-webkit-scrollbar {
@@ -35,14 +35,25 @@ function getTimeAgoTranslations(lang: TimeAgoLang): TimeAgoTranslations {
35
35
  }
36
36
  try {
37
37
  const i18n = getI18n()
38
- const messages = i18n.global.messages as Record<string, { timeAgo?: TimeAgoTranslations }>
38
+ const messages = i18n.global.messages as Record<string, { timeAgo?: Partial<TimeAgoTranslations> }>
39
39
  const localeMessages = messages[lang] || messages.en
40
- return localeMessages?.timeAgo ?? fallback
40
+ const fromLocale = localeMessages?.timeAgo
41
+ return fromLocale ? { ...fallback, ...fromLocale } : fallback
41
42
  } catch {
42
43
  return fallback
43
44
  }
44
45
  }
45
46
 
47
+ function unitLabel(unit: string | TimeUnit | undefined, count: number): string {
48
+ if (unit == null) return ''
49
+ if (typeof unit === 'string') {
50
+ if (count === 1) return unit
51
+ if (unit.endsWith('s')) return unit
52
+ return `${unit}s`
53
+ }
54
+ return count === 1 ? (unit.singular ?? '') : (unit.plural ?? unit.singular ?? '')
55
+ }
56
+
46
57
  function getCurrentLocale(): TimeAgoLang {
47
58
  try {
48
59
  const i18n = getI18n()
@@ -60,7 +71,13 @@ export function timeAgo(
60
71
  langOrConfig?: TimeAgoLang | { lang?: TimeAgoLang, mode?: 'relative' | 'absolute' }
61
72
  ) {
62
73
  if (!date) return ''
63
- if (typeof date === 'string') date = new Date(date)
74
+ if (typeof date === 'string') {
75
+ // Treat bare ISO strings (no timezone offset / Z) as UTC
76
+ if (/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}/.test(date) && !/[Z+-]\d*$/.test(date))
77
+ date = new Date(`${date}Z`)
78
+ else
79
+ date = new Date(date)
80
+ }
64
81
 
65
82
  const lang = typeof langOrConfig === 'string'
66
83
  ? langOrConfig
@@ -80,7 +97,8 @@ export function timeAgo(
80
97
  ]
81
98
 
82
99
  const t = getTimeAgoTranslations(lang)
83
- const getUnit = (label: string): string | TimeUnit => t[label as keyof TimeAgoTranslations] as string | TimeUnit
100
+ const getUnit = (label: string): string | TimeUnit | undefined =>
101
+ t[label as keyof TimeAgoTranslations] as string | TimeUnit | undefined
84
102
 
85
103
  for (const interval of intervals) {
86
104
  const count = Math.floor(Math.abs(seconds) / interval.seconds)
@@ -89,16 +107,14 @@ export function timeAgo(
89
107
  const prefix = isRelative && seconds > 0 && t.in !== 'in' ? `${t.in} ` : ''
90
108
 
91
109
  if (lang === 'he') {
92
- const unit = getUnit(interval.label) as TimeUnit
93
- const form = count === 1 ? unit.singular : unit.plural
110
+ const form = unitLabel(getUnit(interval.label), count)
94
111
  const hePrefix = isRelative
95
112
  ? (seconds < 0 ? `${t.ago} ` : (seconds > 0 ? `${t.in} ` : ''))
96
113
  : ''
97
114
 
98
115
  if (interval.label === 'day' && seconds > 0) {
99
116
  const hours = Math.floor((Math.abs(seconds) % 86400) / 3600)
100
- const hourUnit = t.hour as TimeUnit
101
- const hourForm = hours === 1 ? hourUnit.singular : hourUnit.plural
117
+ const hourForm = unitLabel(t.hour, hours)
102
118
  const main = count === 1 ? form : `${count} ${form}`
103
119
  const hourPart = hours > 0 ? (hours === 1 ? ` ${hourForm}` : ` ${hours} ${hourForm}`) : ''
104
120
  return `${hePrefix}${main}${hourPart}`
@@ -106,10 +122,10 @@ export function timeAgo(
106
122
  return `${hePrefix}${count === 1 ? form : `${count} ${form}`}`
107
123
  }
108
124
 
109
- const label = getUnit(interval.label) as string
125
+ const label = unitLabel(getUnit(interval.label), count)
110
126
  if (interval.label === 'day' && seconds > 0) {
111
127
  const hours = Math.floor((Math.abs(seconds) % 86400) / 3600)
112
- const hourLabel = hours > 1 ? `${t.hour}s` : t.hour as string
128
+ const hourLabel = unitLabel(t.hour, hours)
113
129
  return `${prefix}${count} ${label}${hours > 0 ? ` ${hours} ${hourLabel}` : ''}${suffix}`
114
130
  }
115
131
  return `${prefix}${count} ${label}${suffix}`