@bagelink/vue 1.12.33 → 1.12.36

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.33",
4
+ "version": "1.12.36",
5
5
  "description": "Bagel core sdk packages",
6
6
  "author": {
7
7
  "name": "Bagel Studio",
@@ -90,7 +90,7 @@
90
90
  "signature_pad": "^5.0.9",
91
91
  "vue-i18n": "^11.2.8",
92
92
  "vue-toastification": "^2.0.0-rc.5",
93
- "@bagelink/utils": "1.12.33"
93
+ "@bagelink/utils": "1.12.36"
94
94
  },
95
95
  "scripts": {
96
96
  "dev": "tsx watch src/index.ts",
@@ -1,8 +1,10 @@
1
1
  <script setup lang="ts">
2
2
  import type { AddToCalendarEvent } from '@bagelink/vue'
3
- import { Btn, Dropdown, ListItem } from '@bagelink/vue'
3
+ import { Btn, Dropdown, ListItem, useI18n } from '@bagelink/vue'
4
4
  import { computed } from 'vue'
5
5
 
6
+ const { t } = useI18n()
7
+
6
8
  interface Props {
7
9
  event: AddToCalendarEvent
8
10
  google?: boolean
@@ -26,42 +28,42 @@ const hasExplicitCalendars = computed(() => props.google !== undefined
26
28
 
27
29
  const allCalendars = [
28
30
  {
29
- name: 'Google Calendar',
31
+ key: 'google',
30
32
  icon: 'google',
31
33
  action: 'google',
32
34
  color: '#EA4335', // Google Red
33
35
  prop: 'google' as const,
34
36
  },
35
37
  {
36
- name: 'Apple Calendar',
38
+ key: 'apple',
37
39
  icon: 'apple',
38
40
  action: 'apple',
39
41
  color: '#000000', // Apple Black
40
42
  prop: 'apple' as const,
41
43
  },
42
44
  {
43
- name: 'Outlook',
45
+ key: 'outlook',
44
46
  icon: 'windows',
45
47
  action: 'outlook',
46
48
  color: '#0072C6', // Outlook Blue
47
49
  prop: 'outlook' as const,
48
50
  },
49
51
  {
50
- name: 'Office 365',
52
+ key: 'office365',
51
53
  icon: 'microsoft',
52
54
  action: 'office365',
53
55
  color: '#EA3E23', // Office 365 Orange/Red
54
56
  prop: 'office365' as const,
55
57
  },
56
58
  {
57
- name: 'Yahoo Calendar',
59
+ key: 'yahoo',
58
60
  icon: 'yahoo',
59
61
  action: 'yahoo',
60
62
  color: '#6001D2', // Yahoo Purple
61
63
  prop: 'yahoo' as const,
62
64
  },
63
65
  {
64
- name: 'Calendar (ICS file)',
66
+ key: 'ics',
65
67
  icon: 'calendar',
66
68
  action: 'ics',
67
69
  color: '#96A2B4',
@@ -226,12 +228,12 @@ function handleCalendarClick(type: string) {
226
228
  class="inline-block calendar-btn" :flat="false" :style="{ '--bgl-text-color': singleCalendar.color }"
227
229
  @click="handleCalendarClick(singleCalendar.action)"
228
230
  >
229
- Add to {{ singleCalendar.name }}
231
+ {{ t('addToCalendar.addTo', { name: t(`addToCalendar.${singleCalendar.key}`) }) }}
230
232
  </Btn>
231
233
 
232
234
  <!-- Multiple calendars: show dropdown -->
233
235
  <Dropdown
234
- v-else-if="availableCalendars.length > 1" value="Add to Calendar" icon="calendar" color="white"
236
+ v-else-if="availableCalendars.length > 1" :value="t('addToCalendar.addToCalendar')" icon="calendar" color="white"
235
237
  class="inline-block" :flat="false"
236
238
  >
237
239
  <ListItem
@@ -239,7 +241,7 @@ function handleCalendarClick(type: string) {
239
241
  class="txt16" :style="{ '--bgl-text-color': '#000000', '--bgl-primary': calendar.color }"
240
242
  @click="handleCalendarClick(calendar.action)"
241
243
  >
242
- {{ calendar.name }}
244
+ {{ t(`addToCalendar.${calendar.key}`) }}
243
245
  </ListItem>
244
246
  </Dropdown>
245
247
  </template>
@@ -324,11 +324,11 @@ function onConnectorChange(id: string, connector: LogicalOperator) {
324
324
  <!-- <div v-else /> -->
325
325
 
326
326
  <!-- Field selector -->
327
- <SelectInput
328
- :model-value="condition.field" :options="fields"
329
- :placeholder="currentTexts.placeholders.selectField" class="m-0 light-input borderHover"
330
- @update:model-value="(v: string) => onFieldChange(condition.id, v)"
331
- />
327
+ <SelectInput
328
+ :model-value="condition.field" :options="fields"
329
+ :placeholder="currentTexts.placeholders.selectField" class="m-0 light-input borderHover" searchable
330
+ @update:model-value="(v: string) => onFieldChange(condition.id, v)"
331
+ />
332
332
 
333
333
  <!-- Operator selector -->
334
334
  <SelectInput
@@ -1,3 +1,4 @@
1
+ <!-- eslint-disable vue/multi-word-component-names -->
1
2
  <script lang="ts" setup>
2
3
  import type { BtnOptions } from '@bagelink/vue'
3
4
  import type { SetupContext } from 'vue'
@@ -16,6 +17,7 @@ import '../styles/modal.css'
16
17
 
17
18
  interface ModalProps {
18
19
  thin?: boolean
20
+ mobileThin?: boolean
19
21
  side?: boolean
20
22
  title?: string
21
23
  width?: string
@@ -94,7 +96,7 @@ function openModal() {
94
96
 
95
97
  <Card
96
98
  class="modal m_pt-0" :style="{ ...maxWidth, '--bgl-box-bg': 'var(--bgl-popup-bg)' }" :thin="thin"
97
- :class="{ 'pt-0': thin, 'pt-1': !thin, 'm_mt-5': isOverlay, 'display-flex column': side }" @click.stop
99
+ :class="{ 'pt-0': thin, 'pt-1': !thin, 'm_mt-5': isOverlay, 'display-flex column': side, 'm_px-1 m_pb-1': mobileThin }" @click.stop
98
100
  >
99
101
  <header v-if="slots.toolbar || title" class="tool-bar w-100p flex space-between sticky z-3 py-1">
100
102
  <!-- Header close button -->
@@ -45,7 +45,7 @@ const timeRange = { start: 0, end: 24 }
45
45
 
46
46
  // Check if drag-to-create is enabled based on whether eventCreate handler is provided
47
47
  const isDragToCreateEnabled = computed(() => {
48
- return !!slots.eventCreate || emit.hasOwnProperty('eventCreate')
48
+ return !!slots.eventCreate || Object.prototype.hasOwnProperty.call(emit, 'eventCreate')
49
49
  })
50
50
 
51
51
  // Drag state
@@ -603,11 +603,6 @@ function scrollToTime(time: number) {
603
603
 
604
604
  // Lifecycle hooks
605
605
  onMounted(() => {
606
- console.log('[WeekView] mounted with props:', {
607
- availabilityMode: props.availabilityMode,
608
- availabilityEditable: props.availabilityEditable,
609
- availabilitySlotsCount: props.availabilitySlots?.length
610
- })
611
606
  updateCurrentTimeIndicator()
612
607
  currentTimeInterval.value = setInterval(updateCurrentTimeIndicator, 60000)
613
608
 
@@ -669,6 +664,13 @@ onUnmounted(() => {
669
664
  class="day-column top bottom border-start relative"
670
665
  @mousedown="props.availabilityEditable ? handleAvailMouseDown($event, index) : handleMouseDown($event, day)"
671
666
  >
667
+ <!-- Hour grid lines -->
668
+ <div
669
+ v-for="slot in timeSlots" :key="`line-${slot.time}`"
670
+ class="hour-line absolute start end pointer-events-none"
671
+ :style="{ top: `${slot.hour * slotHeight}px` }"
672
+ />
673
+
672
674
  <!-- Availability painted blocks (behind events) -->
673
675
  <template v-if="props.availabilityMode">
674
676
  <div
@@ -794,6 +796,12 @@ onUnmounted(() => {
794
796
  /* Adjust dot position */
795
797
  }
796
798
 
799
+ .hour-line {
800
+ border-top: 1px solid var(--bgl-gray-80);
801
+ z-index: 0;
802
+ height: 0;
803
+ }
804
+
797
805
  /* This ensures all grid content aligns properly */
798
806
  .overflow {
799
807
  position: relative;
@@ -38,6 +38,11 @@ interface PropTypes {
38
38
  searchPlaceholder?: string
39
39
  error?: string
40
40
  underlined?: boolean
41
+ size?: 'xs' | 's' | 'm' | 'l' | 'xl'
42
+ outline?: boolean
43
+ border?: boolean
44
+ thin?: boolean
45
+ round?: boolean
41
46
  }
42
47
 
43
48
  const searchInput = ref<HTMLElement | undefined>()
@@ -56,6 +61,17 @@ const selected = ref(false)
56
61
  const open = ref(false)
57
62
  const selectPlaceholder = computed(() => resolveI18n(props.placeholder) ?? $t('select.placeholder'))
58
63
 
64
+ const btnClasses = computed(() => ({
65
+ 'selectinput-btn--xs': props.size === 'xs',
66
+ 'selectinput-btn--s': props.size === 's',
67
+ 'selectinput-btn--l': props.size === 'l',
68
+ 'selectinput-btn--xl': props.size === 'xl',
69
+ 'selectinput-btn--round': props.round,
70
+ 'selectinput-btn--thin': props.thin,
71
+ 'outline': props.outline,
72
+ 'border': props.border,
73
+ }))
74
+
59
75
  const selectedLabel = computed((): string => {
60
76
  if (selectedItemCount.value === 0) { return selectPlaceholder.value }
61
77
  if (selectedItemCount.value > 4) {
@@ -73,6 +89,7 @@ const { results, isLoading } = useSearch<Option>({
73
89
  searchTerm: () => searchTerm.value,
74
90
  serverSearch: isAsyncSource(props.options) ? props.options : undefined,
75
91
  items: () => (Array.isArray(props.options) ? props.options : []),
92
+ keysToSearch: ['label'],
76
93
  minChars: isAsyncSource(props.options) ? 0 : 2,
77
94
  })
78
95
 
@@ -275,7 +292,7 @@ onMounted(() => {
275
292
  />
276
293
  <button
277
294
  v-else ref="triggerBtn" :disabled="disabled" type="button" class="selectinput-btn"
278
- :class="{ isEmpty: selectedItemCount === 0 }" @click="open = !open"
295
+ :class="[{ isEmpty: selectedItemCount === 0 }, btnClasses]" @click="open = !open"
279
296
  @keydown.down.prevent="navigate('down')" @keydown.up.prevent="navigate('up')"
280
297
  >
281
298
  <Icon v-if="icon" :icon="icon" />
@@ -320,10 +337,12 @@ onMounted(() => {
320
337
  <Icon v-if="isSelected(option)" :size="1.1" icon="select_check_box" />
321
338
  <Icon v-if="!isSelected(option)" class="opacity-3" icon="check_box_outline_blank" :size="1.1" />
322
339
  </template>
323
- <Icon v-if="getOptionIcon(option)" :icon="getOptionIcon(option)!" :size="1" />
324
- <span class="block">
325
- {{ getLabel(option) }}
326
- </span>
340
+ <div class="flex gap-05">
341
+ <Icon v-if="getOptionIcon(option)" :icon="getOptionIcon(option)!" :size="1" />
342
+ <span class="block">
343
+ {{ getLabel(option) }}
344
+ </span>
345
+ </div>
327
346
  </div>
328
347
  <p v-if="results.length === 0" class="selectinput-option opacity-3 pointer-events-none">
329
348
  No options found
@@ -422,6 +441,13 @@ onMounted(() => {
422
441
  text-overflow: ellipsis;
423
442
  }
424
443
 
444
+ .selectinput-btn.selectinput-btn--xs { height: calc(var(--input-height) * 0.6); padding: 0 0.4rem; font-size: 0.75em; }
445
+ .selectinput-btn.selectinput-btn--s { height: calc(var(--input-height) * 0.75); padding: 0 0.5rem; font-size: 0.875em; }
446
+ .selectinput-btn.selectinput-btn--l { height: calc(var(--input-height) * 1.2); padding: 0 1rem; font-size: 1.1em; }
447
+ .selectinput-btn.selectinput-btn--xl { height: calc(var(--input-height) * 1.5); padding: 0 1.25rem; font-size: 1.2em; }
448
+ .selectinput-btn.selectinput-btn--round { border-radius: 999px; }
449
+ .selectinput-btn.selectinput-btn--thin { height: calc(var(--input-height) * 0.75); padding: 0 0.5rem; }
450
+
425
451
  .selectinput .bagel-input.mb-0 input {
426
452
  /* background: transparent !important; */
427
453
  }
@@ -19,7 +19,7 @@ export { Draggable, useDraggable, vDraggable } from './draggable'
19
19
  export { default as DragOver } from './DragOver.vue'
20
20
  export { default as Dropdown } from './Dropdown.vue'
21
21
  export { default as FieldSetVue } from './FieldSetVue.vue'
22
- export { default as Filter } from './Filter.vue'
22
+ export { default as FilterQuery } from './FilterQuery.vue'
23
23
  export { default as Flag } from './Flag.vue'
24
24
  export * from './form'
25
25
  export { default as Icon } from './Icon/Icon.vue'
@@ -206,12 +206,13 @@ const sidebarStyles = computed(() => {
206
206
  v-for="link in props.footerLinks" :key="link.to || link.label"
207
207
  :title="!menuState.isOpen.value && !menuState.isMobile.value ? resolveI18n(link.label) : ''"
208
208
  :style="{
209
+ backgroundColor: isActiveRoute(link) ? props.activeColor : props.bgColor,
209
210
  color: isActiveRoute(link) ? 'white' : props.textColor,
210
211
  }"
211
- fullWidth
212
- alignTxt="start"
213
- flat :icon="link.icon" class="flex-shrink-0 px-1" :to="link.to" @click="link.action"
212
+ fullWidth alignTxt="start" class="flex-shrink-0 px-1" :class="{ 'nav-btn-active': isActiveRoute(link) }"
213
+ :to="link.to || '/'" @click="link.action"
214
214
  >
215
+ <Icon :name="link.icon" size="1.2" />
215
216
  <span class="nav-text">
216
217
  {{ resolveI18n(link.label) }}
217
218
  </span>
@@ -1,5 +1,6 @@
1
1
  <!-- prettier-ignore-start -->
2
2
  <!-- eslint-disable -->
3
+ <!-- eslint-disable vue/multi-word-component-names -->
3
4
  <script setup lang="ts">
4
5
  import type { DialogWidth, DialogPosition } from './dialogTypes'
5
6
  import { Btn } from '@bagelink/vue'
@@ -171,6 +172,7 @@ dialog {
171
172
  grid-template-rows: auto 1fr auto;
172
173
  overflow: hidden;
173
174
  border-radius: var(--bgl-card-radius, 12px);
175
+ height: 100%;
174
176
  }
175
177
 
176
178
  .height-100-2 {
@@ -478,5 +478,15 @@
478
478
  "eventsCount": "{n} event | {n} events",
479
479
  "noEvents": "No events"
480
480
  }
481
+ },
482
+ "addToCalendar": {
483
+ "addTo": "Add to {name}",
484
+ "addToCalendar": "Add to Calendar",
485
+ "google": "Google Calendar",
486
+ "apple": "Apple Calendar",
487
+ "outlook": "Outlook",
488
+ "office365": "Office 365",
489
+ "yahoo": "Yahoo Calendar",
490
+ "ics": "Calendar (ICS file)"
481
491
  }
482
492
  }
@@ -263,5 +263,9 @@
263
263
  "eventsCount": "{n} evento | {n} eventos",
264
264
  "noEvents": "Sin eventos"
265
265
  }
266
+ },
267
+ "addToCalendar": {
268
+ "addTo": "Agregar a {name}",
269
+ "addToCalendar": "Agregar al calendario"
266
270
  }
267
271
  }
@@ -261,5 +261,10 @@
261
261
  "event": "Événement",
262
262
  "eventsCount": "{n} événement | {n} événements",
263
263
  "noEvents": "Aucun événement"
264
- } }
264
+ }
265
+ },
266
+ "addToCalendar": {
267
+ "addTo": "Ajouter à {name}",
268
+ "addToCalendar": "Ajouter au calendrier"
269
+ }
265
270
  }
@@ -499,5 +499,15 @@
499
499
  "eventsCount": "אירוע אחד | {n} אירועים",
500
500
  "noEvents": "אין אירועים"
501
501
  }
502
+ },
503
+ "addToCalendar": {
504
+ "addTo": "הוסף ל{name}",
505
+ "addToCalendar": "הוסף ליומן",
506
+ "google": "יומן Google",
507
+ "apple": "יומן Apple",
508
+ "outlook": "Outlook",
509
+ "office365": "Office 365",
510
+ "yahoo": "יומן Yahoo",
511
+ "ics": "יומן (קובץ ICS)"
502
512
  }
503
513
  }
@@ -263,5 +263,9 @@
263
263
  "eventsCount": "{n} evento | {n} eventi",
264
264
  "noEvents": "Nessun evento"
265
265
  }
266
+ },
267
+ "addToCalendar": {
268
+ "addTo": "Aggiungi a {name}",
269
+ "addToCalendar": "Aggiungi al calendario"
266
270
  }
267
271
  }
@@ -263,5 +263,9 @@
263
263
  "eventsCount": "{n} событие | {n} события | {n} событий",
264
264
  "noEvents": "Нет событий"
265
265
  }
266
+ },
267
+ "addToCalendar": {
268
+ "addTo": "Добавить в {name}",
269
+ "addToCalendar": "Добавить в календарь"
266
270
  }
267
271
  }