@bagelink/vue 1.4.111 → 1.4.118

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 (59) hide show
  1. package/bin/generateFormSchema.ts +14 -14
  2. package/dist/components/Card.vue.d.ts.map +1 -1
  3. package/dist/components/ImportData.vue.d.ts.map +1 -1
  4. package/dist/components/analytics/PieChart.vue.d.ts.map +1 -1
  5. package/dist/components/calendar/Index.vue.d.ts.map +1 -1
  6. package/dist/components/calendar/index.d.ts +2 -0
  7. package/dist/components/calendar/index.d.ts.map +1 -0
  8. package/dist/components/calendar/views/MonthView.vue.d.ts.map +1 -1
  9. package/dist/components/calendar/views/WeekView.vue.d.ts.map +1 -1
  10. package/dist/components/dataTable/DataTable.vue.d.ts.map +1 -1
  11. package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
  12. package/dist/components/form/inputs/DatePicker.vue.d.ts +1 -0
  13. package/dist/components/form/inputs/DatePicker.vue.d.ts.map +1 -1
  14. package/dist/components/form/inputs/RichText/composables/useEditor.d.ts.map +1 -1
  15. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  16. package/dist/components/form/inputs/RichText/utils/media.d.ts.map +1 -1
  17. package/dist/components/layout/AppContent.vue.d.ts.map +1 -1
  18. package/dist/composables/useSchemaField.d.ts +2 -2
  19. package/dist/composables/useSchemaField.d.ts.map +1 -1
  20. package/dist/index.cjs +5 -5
  21. package/dist/index.mjs +5 -5
  22. package/dist/plugins/modalTypes.d.ts +2 -1
  23. package/dist/plugins/modalTypes.d.ts.map +1 -1
  24. package/dist/plugins/useModal.d.ts +1 -1
  25. package/dist/plugins/useModal.d.ts.map +1 -1
  26. package/dist/style.css +1 -1
  27. package/dist/types/BagelForm.d.ts +40 -19
  28. package/dist/types/BagelForm.d.ts.map +1 -1
  29. package/dist/types/NavLink.d.ts +1 -1
  30. package/dist/types/NavLink.d.ts.map +1 -1
  31. package/dist/utils/BagelFormUtils.d.ts +20 -5
  32. package/dist/utils/BagelFormUtils.d.ts.map +1 -1
  33. package/dist/utils/elementUtils.d.ts.map +1 -1
  34. package/dist/utils/index.d.ts +1 -1
  35. package/dist/utils/index.d.ts.map +1 -1
  36. package/package.json +1 -1
  37. package/src/components/Card.vue +1 -2
  38. package/src/components/DataPreview.vue +1 -1
  39. package/src/components/ImportData.vue +94 -88
  40. package/src/components/analytics/PieChart.vue +21 -34
  41. package/src/components/calendar/Index.vue +15 -35
  42. package/src/components/calendar/views/MonthView.vue +84 -88
  43. package/src/components/calendar/views/WeekView.vue +143 -89
  44. package/src/components/dataTable/DataTable.vue +2 -3
  45. package/src/components/form/BagelForm.vue +3 -6
  46. package/src/components/form/inputs/DateInput.vue +2 -2
  47. package/src/components/form/inputs/DatePicker.vue +40 -47
  48. package/src/components/form/inputs/RichText/utils/media.ts +8 -9
  49. package/src/components/layout/AppContent.vue +21 -1
  50. package/src/composables/useSchemaField.ts +7 -7
  51. package/src/plugins/modalTypes.ts +10 -2
  52. package/src/plugins/useModal.ts +23 -7
  53. package/src/styles/layout.css +6 -0
  54. package/src/types/BagelForm.ts +97 -22
  55. package/src/types/NavLink.ts +1 -1
  56. package/src/utils/BagelFormUtils.ts +63 -34
  57. package/src/utils/elementUtils.ts +1 -4
  58. package/src/utils/index.ts +7 -5
  59. /package/src/components/{dialog → calendar}/index.ts +0 -0
@@ -114,12 +114,9 @@ async function handleSubmit() {
114
114
  }
115
115
 
116
116
  // Field renderingks
117
- const { renderField } = useSchemaField<T, P>({
117
+ const { renderField } = useSchemaField<T>({
118
118
  mode: 'form',
119
- getFormData: () => ({
120
- ...formData.value,
121
- get: (path: string) => getNestedValue(formData.value, path, '')
122
- }),
119
+ getFormData: () => formData.value,
123
120
  onUpdateModelValue: (field, value) => {
124
121
  if (!field.id) return
125
122
 
@@ -128,7 +125,7 @@ const { renderField } = useSchemaField<T, P>({
128
125
  }
129
126
  })
130
127
 
131
- const renderSchemaField = (field: any) => renderField(field as BaseBagelField<T, P>)
128
+ const renderSchemaField = (field: any) => renderField(field as BaseBagelField<T, Path<T>>)
132
129
 
133
130
  // Add new method to handle slot input changes
134
131
  function handleSlotInputChange(event: Event) {
@@ -1,6 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import type { ModeType } from '../../../utils/calendar/typings'
3
- import { TextInput, Dropdown, fmtDate } from '@bagelink/vue'
3
+ import { TextInput, Dropdown, formatDate } from '@bagelink/vue'
4
4
  import { onClickOutside } from '@vueuse/core'
5
5
  import { ref, onMounted } from 'vue'
6
6
  import { WEEK_START_DAY } from '../../../utils/calendar/time'
@@ -47,7 +47,7 @@ const isOpen = ref(false)
47
47
  function useFormatting() {
48
48
  const formatDisplayDate = (date: Date | string | undefined): string => {
49
49
  if (!date) return ''
50
- return fmtDate(date, { fmt: props.enableTime ? 'DD.MM.YY HH:mm' : 'DD.MM.YY' })
50
+ return formatDate(date, { fmt: props.enableTime ? 'DD.MM.YY HH:mm' : 'DD.MM.YY' })
51
51
  }
52
52
 
53
53
  const parseUserInput = (input: string): Date | null => {
@@ -15,6 +15,7 @@ const props = withDefaults(
15
15
  locale?: string
16
16
  enableTime?: boolean
17
17
  highlightedDates?: MaybeRefOrGetter<(string | Date)[]>
18
+ disabledDates?: MaybeRefOrGetter<(string | Date)[]>
18
19
  autoSize?: boolean
19
20
  }>(),
20
21
  {
@@ -28,6 +29,7 @@ const props = withDefaults(
28
29
  const emit = defineEmits(['update:modelValue'])
29
30
 
30
31
  const computedHighlightedDates = $computed(() => toValue(props.highlightedDates))
32
+ const computedDisabledDates = $computed(() => toValue(props.disabledDates))
31
33
 
32
34
  // State
33
35
  const currentMonth = ref(new Date())
@@ -50,8 +52,24 @@ function useDateValidation() {
50
52
  const minDate = parseDate(props.min)
51
53
  const maxDate = parseDate(props.max)
52
54
 
55
+ // Check if date is in min/max range
53
56
  if (minDate && date < minDate) return true
54
57
  if (maxDate && date > maxDate) return true
58
+
59
+ // Check if date is in the disabled dates array
60
+ if (Array.isArray(computedDisabledDates) && computedDisabledDates.length > 0) {
61
+ const isInDisabledDates = computedDisabledDates.some((disabledDate) => {
62
+ const parsedDisabledDate = parseDate(disabledDate)
63
+ if (!parsedDisabledDate) return false
64
+
65
+ // Compare year, month, and day
66
+ return date.getFullYear() === parsedDisabledDate.getFullYear()
67
+ && date.getMonth() === parsedDisabledDate.getMonth()
68
+ && date.getDate() === parsedDisabledDate.getDate()
69
+ })
70
+ if (isInDisabledDates) return true
71
+ }
72
+
55
73
  return false
56
74
  }
57
75
 
@@ -310,7 +328,7 @@ function selectDate(date: Date | null) {
310
328
  </script>
311
329
 
312
330
  <template>
313
- <div class="ltr gap-075 m_flex-wrap calendar-container justify-content-center h-100p" :class="{ 'flex': !autoSize }">
331
+ <div class="ltr gap-075 m_flex-wrap calendar-container justify-content-center h-100p" :class="{ flex: !autoSize }">
314
332
  <div class="calendar-section m_border-none px-05 m_p-0">
315
333
  <div class="flex space-between pb-1">
316
334
  <template v-if="currentView === 'days'">
@@ -333,18 +351,12 @@ function selectDate(date: Date | null) {
333
351
  </div>
334
352
 
335
353
  <div v-if="currentView === 'days'" class="calendar-grid grid gap-025">
336
- <div
337
- v-for="day in weekDays"
338
- :key="day"
339
- class="txt-center txt-12 opacity-6"
340
- >
354
+ <div v-for="day in weekDays" :key="day" class="txt-center txt-12 opacity-6">
341
355
  {{ day }}
342
356
  </div>
343
357
 
344
358
  <button
345
- v-for="date in currentMonthDays"
346
- :key="date?.toISOString()"
347
- type="button"
359
+ v-for="date in currentMonthDays" :key="date?.toISOString()" type="button"
348
360
  class="day aspect-ratio-1 flex align-items-center justify-content-center pointer round txt14 p-0"
349
361
  :class="{
350
362
  'selected': isSelected(date),
@@ -352,9 +364,7 @@ function selectDate(date: Date | null) {
352
364
  'disabled': isDateDisabled(date),
353
365
  'not-in-month': isNotInMonth(date),
354
366
  'highlighted': isHighlighted(date),
355
- }"
356
- :disabled="isDateDisabled(date)"
357
- @click="selectDate(date)"
367
+ }" :disabled="isDateDisabled(date)" @click="selectDate(date)"
358
368
  >
359
369
  {{ date?.getDate() }}
360
370
  </button>
@@ -362,52 +372,34 @@ function selectDate(date: Date | null) {
362
372
 
363
373
  <div v-else-if="currentView === 'months'" class="month-grid grid gap-05 p-05">
364
374
  <Btn
365
- v-for="month in months"
366
- :key="month.value"
367
- thin
368
- :flat="month.value !== currentMonthValue.month"
369
- :disabled="month.disabled"
370
- :value="month.name"
371
- @click="selectMonth(month.value)"
375
+ v-for="month in months" :key="month.value" thin :flat="month.value !== currentMonthValue.month"
376
+ :disabled="month.disabled" :value="month.name" @click="selectMonth(month.value)"
372
377
  />
373
378
  </div>
374
379
 
375
380
  <div v-else class="year-grid grid gap-05 p-0">
376
381
  <Btn
377
- v-for="year in years"
378
- :key="year.value" thin
379
- :flat="year.value !== currentMonthValue.year"
380
- :disabled="year.disabled"
381
- :value="year.value.toString()"
382
- @click="selectYear(year.value)"
382
+ v-for="year in years" :key="year.value" thin :flat="year.value !== currentMonthValue.year"
383
+ :disabled="year.disabled" :value="year.value.toString()" @click="selectYear(year.value)"
383
384
  />
384
385
  </div>
385
386
  </div>
386
387
 
387
- <div v-if="enableTime && currentView === 'days'" class="time-picker border-start flex column gap-1 w-120px px-025">
388
+ <div
389
+ v-if="enableTime && currentView === 'days'"
390
+ class="time-picker border-start flex column gap-1 w-120px px-025"
391
+ >
388
392
  <div class="flex gap-025">
389
393
  <NumberInput
390
- center
391
- :modelValue="hours"
392
- :disabled="!selectedDate"
393
- :min="0"
394
- :max="23"
395
- layout="vertical"
396
- :padZero="2"
397
- @update:modelValue="handleHourInput"
394
+ center :modelValue="hours" :disabled="!selectedDate" :min="0" :max="23" layout="vertical"
395
+ :padZero="2" @update:modelValue="handleHourInput"
398
396
  />
399
397
  <p class="pb-075">
400
398
  :
401
399
  </p>
402
400
  <NumberInput
403
- center
404
- :modelValue="minutes"
405
- :disabled="!selectedDate"
406
- :min="0"
407
- :max="59"
408
- :padZero="2"
409
- layout="vertical"
410
- @update:modelValue="handleMinuteInput"
401
+ center :modelValue="minutes" :disabled="!selectedDate" :min="0" :max="59" :padZero="2"
402
+ layout="vertical" @update:modelValue="handleMinuteInput"
411
403
  />
412
404
  </div>
413
405
  </div>
@@ -478,6 +470,7 @@ function selectDate(date: Date | null) {
478
470
  color: var(--bgl-text-color);
479
471
  outline: 1px solid var(--border-color);
480
472
  }
473
+
481
474
  .day:hover:not(.disabled).selected {
482
475
  filter: var(--bgl-hover-filter);
483
476
  background-color: var(--bgl-primary);
@@ -504,16 +497,16 @@ function selectDate(date: Date | null) {
504
497
  }
505
498
 
506
499
  .day.highlighted:not(.selected) {
507
- background-color: var(--bgl-secondary-light, rgba(var(--bgl-primary-rgb, 0, 123, 255), 0.15));
508
- font-weight: 500;
500
+ background-color: var(--bgl-secondary-light, rgba(var(--bgl-primary-rgb, 0, 123, 255), 0.15));
501
+ font-weight: 500;
509
502
  }
510
503
 
511
504
  .day.highlighted.selected {
512
- /* Add a subtle ring effect for dates that are both selected and highlighted */
513
- box-shadow: 0 0 0 2px var(--bgl-secondary, rgba(var(--bgl-primary-rgb, 0, 123, 255), 0.5));
505
+ /* Add a subtle ring effect for dates that are both selected and highlighted */
506
+ box-shadow: 0 0 0 2px var(--bgl-secondary, rgba(var(--bgl-primary-rgb, 0, 123, 255), 0.5));
514
507
  }
515
508
 
516
509
  .day.highlighted:not(.selected):hover {
517
- background-color: var(--bgl-secondary-light-hover, rgba(var(--bgl-primary-rgb, 0, 123, 255), 0.25));
510
+ background-color: var(--bgl-secondary-light-hover, rgba(var(--bgl-primary-rgb, 0, 123, 255), 0.25));
518
511
  }
519
512
  </style>
@@ -1,8 +1,7 @@
1
- import type { BaseBagelField } from '@bagelink/vue'
2
1
  import type { ModalApi } from '../../../../../plugins/useModal'
3
2
 
4
3
  import type { EditorState } from '../richTextTypes'
5
- import { bagelFormUtils as bglFrmUtil } from '@bagelink/vue'
4
+ import { bagelFormUtils as frm } from '../../../../../utils'
6
5
 
7
6
  export function insertImage(modal: ModalApi, state: EditorState) {
8
7
  const { range, doc } = state
@@ -19,9 +18,9 @@ export function insertImage(modal: ModalApi, state: EditorState) {
19
18
  schema: [
20
19
  { id: 'src', $el: 'file', attrs: { bindkey: 'url' } },
21
20
  { id: 'alt', $el: 'text', label: 'Alt Text' },
22
- bglFrmUtil.frmRow(
23
- bglFrmUtil.numField('width', 'Width', { min: 1 }),
24
- bglFrmUtil.numField('height', 'Height', { min: 1 }),
21
+ frm.frmRow(
22
+ frm.numField('width', 'Width', { min: 1 }),
23
+ frm.numField('height', 'Height', { min: 1 }),
25
24
  ),
26
25
  { id: 'figcaption', $el: 'check', label: 'Show Caption' },
27
26
  ],
@@ -86,11 +85,11 @@ export function insertEmbed(modal: ModalApi, state: EditorState) {
86
85
  title: 'Insert Embed',
87
86
  schema: [
88
87
  { id: 'url', $el: 'text', label: 'URL', attrs: { placeholder: 'Enter URL (YouTube, Vimeo, etc.)' } },
89
- bglFrmUtil.frmRow(
90
- bglFrmUtil.numField('width', 'Width', { min: 200, placeholder: '560' }),
91
- bglFrmUtil.numField('height', 'Height', { min: 200, placeholder: '315' })
88
+ frm.frmRow(
89
+ frm.numField('width', 'Width', { min: 200, placeholder: '560' }),
90
+ frm.numField('height', 'Height', { min: 200, placeholder: '315' })
92
91
  ),
93
- { id: 'allowFullscreen', $el: 'check', label: 'Allow Fullscreen', value: true } as BaseBagelField<InsertImbedModalData, 'allowFullscreen'>,
92
+ { id: 'allowFullscreen', $el: 'check', label: 'Allow Fullscreen', attrs: { value: true } },
94
93
  ],
95
94
  onSubmit: (data: { url: string, width?: number, height?: number, allowFullscreen?: boolean }) => {
96
95
  if (!data.url) return
@@ -66,7 +66,7 @@ const sidebarCardStyle = inject('sidebarCardStyle', { value: true })
66
66
  </header>
67
67
 
68
68
  <!-- Page Content -->
69
- <main class="flex-grow overflow py-1 w-100p m_p-05 m_scrollbar-gutter-stable-both m_vw100" :class="{
69
+ <main class="pageContent flex-grow overflow py-1 w-100p m_p-05 m_scrollbar-gutter-stable-both m_vw100" :class="{
70
70
  'px-1': !sidebarCardStyle?.value,
71
71
  }">
72
72
  <slot name="content">
@@ -77,6 +77,26 @@ const sidebarCardStyle = inject('sidebarCardStyle', { value: true })
77
77
  </div>
78
78
  </template>
79
79
 
80
+ <style>
81
+ .slide-fade-enter-from:has(.app-header),
82
+ .slide-fade-leave-to:has(.app-header) {
83
+ transform: translateX(0) !important;
84
+ opacity: 1 !important;
85
+ }
86
+
87
+ .slide-fade-enter-from:has(.app-header) .pageContent,
88
+ .slide-fade-leave-to:has(.app-header) .pageContent {
89
+ transform: translateX(-20px) !important;
90
+ opacity: 0 !important;
91
+ }
92
+
93
+ .slide-fade-enter-active:has(.app-header) .pageContent,
94
+ .slide-fade-leave-active:has(.app-header) .pageContent {
95
+ transition: all 0.15s ease-in;
96
+ overflow: hidden;
97
+ }
98
+ </style>
99
+
80
100
  <style scoped>
81
101
  .paddingAppContent {
82
102
  padding-inline-start: 0.5rem;
@@ -34,7 +34,7 @@ export interface UseSchemaFieldOptions<T, SFP extends Path<T>> {
34
34
  includeUnset?: boolean
35
35
  }
36
36
 
37
- export function useSchemaField<T extends { [key: string]: any }, SP extends Path<T>>(optns: UseSchemaFieldOptions<T, SP>) {
37
+ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchemaFieldOptions<T, Path<T>>) {
38
38
  const { mode = 'form', getFormData, onUpdateModelValue, includeUnset = false } = optns
39
39
 
40
40
  // Helper function to render objects recursively
@@ -96,18 +96,18 @@ export function useSchemaField<T extends { [key: string]: any }, SP extends Path
96
96
  return typeof field.$el === 'object' ? field.$el : componentMap[field.$el as keyof typeof componentMap] ?? field.$el ?? 'div'
97
97
  }
98
98
 
99
- function renderChild(child: SchemaChild<T, SP>, slots?: BaseBagelField<T, SP>['slots']) {
99
+ function renderChild(child: SchemaChild<T, Path<T>>, slots?: BaseBagelField<T, Path<T>>['slots']) {
100
100
  if (typeof child === 'string') return child
101
101
  if (isVNode(child)) return child
102
102
  return renderField(
103
- child as BaseBagelField<T, SP>,
103
+ child as BaseBagelField<T, Path<T>>,
104
104
  slots
105
105
  )
106
106
  }
107
107
 
108
108
  function renderField(
109
- field: BaseBagelField<T, SP>,
110
- slots?: BaseBagelField<T, SP>['slots']
109
+ field: BaseBagelField<T, Path<T>>,
110
+ slots?: BaseBagelField<T, Path<T>>['slots']
111
111
  ): VNode | undefined {
112
112
  const Component = getComponent(field as Field<T>)
113
113
  if (!Component) return
@@ -320,7 +320,7 @@ export function useSchemaField<T extends { [key: string]: any }, SP extends Path
320
320
  return schemaField
321
321
  }
322
322
 
323
- return renderField(schemaField as BaseBagelField<T, SP>, slots)
323
+ return renderField(schemaField as BaseBagelField<T, Path<T>>, slots)
324
324
  })
325
325
  }
326
326
  }
@@ -329,7 +329,7 @@ export function useSchemaField<T extends { [key: string]: any }, SP extends Path
329
329
 
330
330
  // Handle custom slot content from parent
331
331
 
332
- const slotContent = field.id ? (slots?.[field.id] as VNodeFn<T, SP> | undefined)?.({ row: rowData, field }) : undefined
332
+ const slotContent = field.id ? (slots?.[field.id] as VNodeFn<T, Path<T>> | undefined)?.({ row: rowData, field }) : undefined
333
333
  // field.id && slots?.[field.id] && typeof slots[field.id] === 'function' && !Array.isArray(slots?.[field.id])
334
334
  // ? (slots[field.id])({ row: rowData, field })
335
335
  // : undefined
@@ -1,5 +1,6 @@
1
- import type { BglFormSchemaT, BtnOptions, ThemeType } from '@bagelink/vue'
2
1
  import type { MaybeRefOrGetter } from 'vue'
2
+ import type { BtnOptions, ThemeType } from '../types'
3
+ import type { BglFormSchemaT } from '../types/BagelForm'
3
4
 
4
5
  export interface ModalOptions {
5
6
  title?: string
@@ -25,7 +26,14 @@ export interface ModalConfirmOptions {
25
26
  }
26
27
 
27
28
  export type ModalType = 'modal' | 'modalForm' | 'confirmModal'
28
- export type ConfirmModalUserOptions = string | { title: string, message: string, confirmText?: string, cancelText?: string, confirmBtnColor?: string, cancelBtnColor?: string }
29
+ export type ConfirmModalUserOptions = string | {
30
+ title: string
31
+ message: string
32
+ confirmText?: string
33
+ cancelText?: string
34
+ confirmBtnColor?: string
35
+ cancelBtnColor?: string
36
+ }
29
37
 
30
38
  export interface ModalComponentProps<T extends { [key: string]: any }> {
31
39
  componentSlots: { [key: string]: any }
@@ -1,12 +1,26 @@
1
1
  import type { InjectionKey, Plugin } from 'vue'
2
2
  import type { ComponentProps } from 'vue-component-type-helpers'
3
- import type { ConfirmModalUserOptions, ModalComponentProps, ModalConfirmOptions, ModalFormComponentProps, ModalFormOptions, ModalOptions, ModalType } from './modalTypes'
4
- import { Modal, ModalConfirm, ModalForm } from '@bagelink/vue'
3
+ import type {
4
+ ModalComponentProps,
5
+ ModalFormComponentProps,
6
+ ModalFormOptions,
7
+ ModalOptions,
8
+ ModalType,
9
+ ConfirmModalUserOptions,
10
+ ModalConfirmOptions
11
+ } from './modalTypes'
5
12
  import { defineComponent, h, inject } from 'vue'
13
+ import { Modal, ModalConfirm, ModalForm } from '../components'
6
14
 
7
15
  export interface ModalApi {
8
- showModal: <T extends { [key: string]: any }>(options: ModalOptions, slots?: { [key: string]: any }) => ModalComponentProps<T> | undefined
9
- showModalForm: <T extends { [key: string]: any }>(options: ModalFormOptions<T>, slots?: { [key: string]: any }) => ModalFormComponentProps<T> | undefined
16
+ showModal: <T extends { [key: string]: any }>(
17
+ options: ModalOptions,
18
+ slots?: { [key: string]: any }
19
+ ) => ModalComponentProps<T> | undefined
20
+ showModalForm: <T extends { [key: string]: any }>(
21
+ options: ModalFormOptions<T>,
22
+ slots?: { [key: string]: any }
23
+ ) => ModalFormComponentProps<T> | undefined
10
24
  hideModal: (index?: number) => void
11
25
  confirmModal: (options: ConfirmModalUserOptions) => Promise<boolean>
12
26
  }
@@ -21,7 +35,7 @@ export function useModal(): ModalApi {
21
35
 
22
36
  export const ModalPlugin: Plugin = {
23
37
  install: (app) => {
24
- const modalStack = $ref<ModalComponentProps<object>[]>([])
38
+ const modalStack: ModalComponentProps<object>[] = []
25
39
 
26
40
  const hideModal = (index: number) => {
27
41
  modalStack.splice(index, 1)
@@ -59,7 +73,10 @@ export const ModalPlugin: Plugin = {
59
73
  app.provide(ModalSymbol, {
60
74
  showModal: (options: ModalOptions, slots?: { [key: string]: any }) => showModal('modal', options, slots),
61
75
 
62
- showModalForm: <T extends { [key: string]: any }>(options: ModalFormOptions<T>, slots?: { [key: string]: any }) => showModal<T>('modalForm', options, slots) as ModalFormComponentProps<T>,
76
+ showModalForm: <T extends { [key: string]: any }>(
77
+ options: ModalFormOptions<T>,
78
+ slots?: { [key: string]: any }
79
+ ) => showModal<T>('modalForm', options, slots) as ModalFormComponentProps<T>,
63
80
 
64
81
  confirmModal: (options: ConfirmModalUserOptions) => confirmModal(options),
65
82
 
@@ -80,7 +97,6 @@ export const ModalPlugin: Plugin = {
80
97
  case 'modalForm':
81
98
  return h(ModalForm, props as ComponentProps<typeof ModalForm>, modal.componentSlots)
82
99
  case 'confirmModal':
83
-
84
100
  return h(ModalConfirm, props as ModalConfirmOptions, {})
85
101
  default:
86
102
  return h(Modal, props, modal.componentSlots)
@@ -1022,6 +1022,12 @@
1022
1022
  width: 100%;
1023
1023
  }
1024
1024
 
1025
+ .w-100i,
1026
+ .w-100pi,
1027
+ .w100pi .width-100i {
1028
+ width: 100% !important;
1029
+ }
1030
+
1025
1031
  .min-w-100p,
1026
1032
  .w-min-100p,
1027
1033
  .min-w100p {
@@ -1,10 +1,11 @@
1
- import type { ArrayAttrs, FieldArray, SelectInput, TextInput, Option } from '@bagelink/vue'
1
+ // Local type definitions for internal use only
2
+ type ArrayAttrs = any
3
+ interface Option { label: string, value: any }
2
4
  import type { Paths, Get, IterableElement, OmitIndexSignature } from 'type-fest'
3
5
  import type { ToString } from 'type-fest/source/internal'
4
6
  import type { LiteralStringUnion } from 'type-fest/source/literal-union'
5
7
  import type { PathsOptions, DefaultPathsOptions } from 'type-fest/source/paths'
6
8
  import type { VNode } from 'vue'
7
- import type { ComponentExposed } from 'vue-component-type-helpers'
8
9
 
9
10
  export type AttributeValue =
10
11
  | string
@@ -14,7 +15,7 @@ export type AttributeValue =
14
15
  | { [key: string]: any }
15
16
 
16
17
  export type AttributeFn<T, P extends Path<T>> = (
17
- field: FieldVal<T, P>,
18
+ field: SmartFieldVal<T, P>,
18
19
  row?: T
19
20
  ) => AttributeValue
20
21
 
@@ -34,16 +35,16 @@ export type BagelFieldOptions<T, P extends Path<T>> =
34
35
  | boolean
35
36
  | { [key: string]: any }
36
37
  )[]
37
- | ((val?: FieldVal<T, P>, rowData?: T) => Option[] | ((query: string) => Promise<Option[]>))
38
- | ((query: string, val?: FieldVal<T, P>, rowData?: T) => Promise<Option[]>)
38
+ | ((val?: SmartFieldVal<T, P>, rowData?: T) => Option[] | ((query: string) => Promise<Option[]>))
39
+ | ((query: string, val?: SmartFieldVal<T, P>, rowData?: T) => Promise<Option[]>)
39
40
 
40
41
  export type VIfType<T, P extends Path<T>> =
41
42
  | string
42
43
  | boolean
43
- | ((val?: FieldVal<T, P>, rowData?: T) => boolean)
44
+ | ((val?: SmartFieldVal<T, P>, rowData?: T) => boolean)
44
45
 
45
46
  export type ValidationFn<T, P extends Path<T>> = (
46
- val?: FieldVal<T, P>,
47
+ val?: SmartFieldVal<T, P>,
47
48
  rowData?: T
48
49
  ) => string | undefined
49
50
 
@@ -56,10 +57,84 @@ export type _Path<
56
57
  PO extends PathsOptions = DefaultPathsOptions,
57
58
  > = ToString<Paths<OmitIndexSignature<T>, PO>>
58
59
 
60
+ // Utility type for open-ended object paths
61
+ export type OpenEndedPath<T> =
62
+ keyof T extends infer K ?
63
+ K extends keyof T ?
64
+ T[K] extends { [key: string]: any } ?
65
+ `${K & string}.${string}`
66
+ : never
67
+ : never
68
+ : never
69
+
70
+ // Enhanced Path type that allows flexibility for nested open-ended objects
59
71
  export type Path<T, PO extends PathsOptions = DefaultPathsOptions> =
60
- FieldVal<T, _Path<T, PO>> extends Array<any>
61
- ? LiteralStringUnion<_Path<T, PO>>
62
- : _Path<T, PO>
72
+ FieldVal<T, _Path<T, PO>> extends Array<any>
73
+ ? LiteralStringUnion<_Path<T, PO>>
74
+ : _Path<T, PO> | (
75
+ // Allow nested paths for properties that have index signatures
76
+ keyof T extends infer K ?
77
+ K extends keyof T ?
78
+ T[K] extends { [key: string]: any } ?
79
+ `${K & string}.${string}`
80
+ : never
81
+ : never
82
+ : never
83
+ )
84
+
85
+ // Smart field value type that preserves type information when possible
86
+ export type SmartFieldVal<T, P extends Path<T>> =
87
+ P extends string
88
+ ? P extends keyof T
89
+ ? T[P]
90
+ : any
91
+ : FieldVal<T, P>
92
+
93
+ // Smart bagel field options that preserve type information
94
+ export type SmartBagelFieldOptions<T, P extends Path<T>> =
95
+ | string
96
+ | (
97
+ | {
98
+ label?: string
99
+ value: string | number
100
+ }
101
+ | string
102
+ | number
103
+ | boolean
104
+ | { [key: string]: any }
105
+ )[]
106
+ | ((val?: SmartFieldVal<T, P>, rowData?: T) => Option[] | ((query: string) => Promise<Option[]>))
107
+ | ((query: string, val?: SmartFieldVal<T, P>, rowData?: T) => Promise<Option[]>)
108
+
109
+ // Smart VIf type that preserves type information
110
+ export type SmartVIfType<T, P extends Path<T>> =
111
+ | string
112
+ | boolean
113
+ | ((val?: SmartFieldVal<T, P>, rowData?: T) => boolean)
114
+
115
+ // Smart validation function that preserves type information
116
+ export type SmartValidationFn<T, P extends Path<T>> = (
117
+ val?: SmartFieldVal<T, P>,
118
+ rowData?: T
119
+ ) => string | undefined
120
+
121
+ // Smart attribute function that preserves type information
122
+ export type SmartAttributeFn<T, P extends Path<T>> = (
123
+ field: SmartFieldVal<T, P>,
124
+ row?: T
125
+ ) => AttributeValue
126
+
127
+ // Smart transform function that preserves type information
128
+ export type SmartTransformFn<T, P extends Path<T>> = (
129
+ val?: SmartFieldVal<T, P>,
130
+ rowData?: T
131
+ ) => any
132
+
133
+ // Smart update function that preserves type information
134
+ export type SmartUpdateFn<T, P extends Path<T>> = (
135
+ val?: SmartFieldVal<T, P>,
136
+ rowData?: T
137
+ ) => unknown
63
138
 
64
139
  /** The value type at path P in object T. */
65
140
  // Fall back to unknown if type resolution fails
@@ -93,7 +168,7 @@ export type SchemaChild<
93
168
  T,
94
169
  P extends Path<T, PO>,
95
170
  PO extends PathsOptions = DefaultPathsOptions,
96
- > = Field<T, PO> | ElementField<T, PO> | VNode | VNodeFn<T, P> | string
171
+ > = Field<T, PO> | ElementField<T, PO> | VNode | VNodeFn<T, P> | string | BaseBagelField<T, P, PO>
97
172
 
98
173
  export interface BaseBagelField<
99
174
  T,
@@ -104,20 +179,20 @@ export interface BaseBagelField<
104
179
  'id'?: P
105
180
  'label'?: string
106
181
  'placeholder'?: string
107
- 'class'?: AttributeValue | AttributeFn<T, P>
182
+ 'class'?: AttributeValue | SmartAttributeFn<T, P>
108
183
  'attrs'?: Attributes<T, P>
109
184
  'required'?: boolean
110
185
  'disabled'?: boolean
111
186
  'helptext'?: string
112
- 'options'?: BagelFieldOptions<T, P>
187
+ 'options'?: SmartBagelFieldOptions<T, P>
113
188
  'children'?: SchemaChild<T, Path<T, PO>, PO>[]
114
189
  'slots'?: { [key: string]: SchemaChild<T, Path<T, PO>, PO>[] }
115
190
  'defaultValue'?: any
116
- 'vIf'?: VIfType<T, P>
117
- 'v-if'?: VIfType<T, P>
118
- 'transform'?: (val?: FieldVal<T, P>, rowData?: T) => any
119
- 'onUpdate'?: (val?: FieldVal<T, P>, rowData?: T) => unknown
120
- 'validate'?: ValidationFn<T, P>
191
+ 'vIf'?: SmartVIfType<T, P>
192
+ 'v-if'?: SmartVIfType<T, P>
193
+ 'transform'?: SmartTransformFn<T, P>
194
+ 'onUpdate'?: SmartUpdateFn<T, P>
195
+ 'validate'?: SmartValidationFn<T, P>
121
196
  }
122
197
 
123
198
  export type _MappedBaseBagelField<
@@ -170,7 +245,7 @@ export interface InputBagelField<
170
245
  PO extends PathsOptions = DefaultPathsOptions
171
246
  >
172
247
  extends BaseBagelField<T, P, PO> {
173
- $el: 'text' | ComponentExposed<typeof TextInput>
248
+ $el: 'text' | any
174
249
  type?: string
175
250
  }
176
251
 
@@ -180,7 +255,7 @@ export interface SelectBagelField<
180
255
  PO extends PathsOptions = DefaultPathsOptions,
181
256
  >
182
257
  extends BaseBagelField<T, P, PO> {
183
- $el: 'select' | ComponentExposed<typeof SelectInput>
258
+ $el: 'select' | any
184
259
  type?: string
185
260
  }
186
261
 
@@ -190,8 +265,8 @@ export interface ArrayBagelField<
190
265
  PO extends PathsOptions = DefaultPathsOptions,
191
266
  >
192
267
  extends BaseBagelField<T, P, PO> {
193
- $el: 'array' | ComponentExposed<typeof FieldArray>
194
- attrs?: ArrayAttrs<T, P>
268
+ $el: 'array' | any
269
+ attrs?: ArrayAttrs
195
270
  }
196
271
 
197
272
  export interface ValidateInputBaseT {
@@ -1,4 +1,4 @@
1
- import type { IconType } from '@bagelink/vue'
1
+ import type { IconType } from './index'
2
2
 
3
3
  export interface NavLink {
4
4
  label: string