@bagelink/vue 1.5.15 → 1.5.20

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 (135) hide show
  1. package/bin/experimentalGenTypedRoutes.ts +15 -15
  2. package/bin/generateFormSchema.ts +12 -12
  3. package/bin/utils.ts +4 -4
  4. package/dist/components/Dropdown.vue.d.ts.map +1 -1
  5. package/dist/components/RouterWrapper.vue.d.ts.map +1 -1
  6. package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
  7. package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
  8. package/dist/components/form/FieldArray.vue.d.ts +5 -4
  9. package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
  10. package/dist/components/form/inputs/CheckInput.vue.d.ts.map +1 -1
  11. package/dist/components/form/inputs/RichText/index.vue.d.ts +1 -0
  12. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  13. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  14. package/dist/components/form/inputs/ToggleInput.vue.d.ts.map +1 -1
  15. package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts.map +1 -1
  16. package/dist/composables/useFormField.d.ts.map +1 -1
  17. package/dist/composables/useSchemaField.d.ts.map +1 -1
  18. package/dist/index.cjs +68 -55
  19. package/dist/index.mjs +34035 -143
  20. package/dist/style.css +1 -1
  21. package/package.json +1 -1
  22. package/src/components/AccordionItem.vue +2 -2
  23. package/src/components/AddToCalendar.vue +1 -1
  24. package/src/components/BglVideo.vue +8 -8
  25. package/src/components/Btn.vue +9 -9
  26. package/src/components/Card.vue +4 -4
  27. package/src/components/Carousel.vue +44 -44
  28. package/src/components/DataPreview.vue +1 -1
  29. package/src/components/DragOver.vue +6 -6
  30. package/src/components/Dropdown.vue +14 -14
  31. package/src/components/Flag.vue +3 -3
  32. package/src/components/Icon/Icon.vue +13 -13
  33. package/src/components/Image.vue +4 -4
  34. package/src/components/ImportData.vue +79 -79
  35. package/src/components/ListItem.vue +7 -7
  36. package/src/components/MapEmbed/Index.vue +6 -6
  37. package/src/components/Modal.vue +10 -10
  38. package/src/components/ModalForm.vue +4 -4
  39. package/src/components/NavBar.vue +2 -2
  40. package/src/components/Pagination.vue +9 -9
  41. package/src/components/Pill.vue +1 -1
  42. package/src/components/Rating.vue +2 -2
  43. package/src/components/RouterWrapper.vue +3 -3
  44. package/src/components/Slider.vue +77 -77
  45. package/src/components/Spreadsheet/Index.vue +34 -34
  46. package/src/components/Spreadsheet/SpreadsheetTable.vue +3 -3
  47. package/src/components/Zoomer.vue +28 -28
  48. package/src/components/analytics/BarChart.vue +6 -6
  49. package/src/components/analytics/KpiCard.vue +2 -2
  50. package/src/components/analytics/LineChart.vue +14 -14
  51. package/src/components/analytics/PieChart.vue +11 -11
  52. package/src/components/calendar/CalendarPopover.vue +1 -1
  53. package/src/components/calendar/Index.vue +1 -1
  54. package/src/components/calendar/views/AgendaView.vue +2 -2
  55. package/src/components/calendar/views/DayView.vue +6 -6
  56. package/src/components/calendar/views/MonthView.vue +2 -2
  57. package/src/components/calendar/views/WeekView.vue +18 -18
  58. package/src/components/dataTable/DataTable.vue +3 -3
  59. package/src/components/dataTable/useSorting.ts +1 -1
  60. package/src/components/dataTable/useTableData.ts +15 -15
  61. package/src/components/dataTable/useTableSelection.ts +8 -8
  62. package/src/components/dataTable/useTableVirtualization.ts +1 -1
  63. package/src/components/draggable/useDraggable.ts +42 -42
  64. package/src/components/form/BagelForm.vue +66 -23
  65. package/src/components/form/BglMultiStepForm.vue +18 -18
  66. package/src/components/form/FieldArray.vue +177 -67
  67. package/src/components/form/inputs/CheckInput.vue +2 -1
  68. package/src/components/form/inputs/CodeEditor/Index.vue +1 -1
  69. package/src/components/form/inputs/CodeEditor/format.ts +7 -7
  70. package/src/components/form/inputs/CodeEditor/useHighlight.ts +6 -6
  71. package/src/components/form/inputs/DateInput.vue +6 -6
  72. package/src/components/form/inputs/DatePicker.vue +19 -19
  73. package/src/components/form/inputs/EmailInput.vue +14 -14
  74. package/src/components/form/inputs/NumberInput.vue +6 -6
  75. package/src/components/form/inputs/OTP.vue +3 -3
  76. package/src/components/form/inputs/RadioGroup.vue +1 -1
  77. package/src/components/form/inputs/RadioPillsInput.vue +8 -8
  78. package/src/components/form/inputs/RichText/components/EditorToolbar.vue +10 -10
  79. package/src/components/form/inputs/RichText/components/TableGridSelector.vue +1 -1
  80. package/src/components/form/inputs/RichText/composables/useCommands.ts +1 -1
  81. package/src/components/form/inputs/RichText/composables/useEditor.ts +12 -12
  82. package/src/components/form/inputs/RichText/composables/useEditorKeyboard.ts +1 -1
  83. package/src/components/form/inputs/RichText/index.vue +300 -132
  84. package/src/components/form/inputs/RichText/utils/commands.ts +69 -69
  85. package/src/components/form/inputs/RichText/utils/debug.ts +1 -1
  86. package/src/components/form/inputs/RichText/utils/formatting.ts +39 -39
  87. package/src/components/form/inputs/RichText/utils/media.ts +6 -6
  88. package/src/components/form/inputs/RichText/utils/selection.ts +28 -28
  89. package/src/components/form/inputs/RichText/utils/table.ts +19 -19
  90. package/src/components/form/inputs/SelectBtn.vue +1 -1
  91. package/src/components/form/inputs/SelectInput.vue +50 -26
  92. package/src/components/form/inputs/SignaturePad.vue +15 -15
  93. package/src/components/form/inputs/TableField.vue +1 -1
  94. package/src/components/form/inputs/TelInput.vue +6 -6
  95. package/src/components/form/inputs/TextInput.vue +5 -5
  96. package/src/components/form/inputs/ToggleInput.vue +2 -1
  97. package/src/components/form/inputs/Upload/UploadInput.vue +155 -102
  98. package/src/components/form/inputs/Upload/upload.ts +1 -1
  99. package/src/components/form/inputs/Upload/useFileUpload.ts +6 -6
  100. package/src/components/form/useBagelFormState.ts +5 -5
  101. package/src/components/layout/AppContent.vue +1 -1
  102. package/src/components/layout/AppLayout.vue +1 -1
  103. package/src/components/layout/Layout.vue +4 -4
  104. package/src/components/layout/TabbedLayout.vue +1 -1
  105. package/src/components/layout/Tabs.vue +2 -2
  106. package/src/components/layout/TabsNav.vue +7 -7
  107. package/src/components/lightbox/Lightbox.vue +8 -8
  108. package/src/components/lightbox/index.ts +8 -8
  109. package/src/composables/index.ts +2 -2
  110. package/src/composables/useAddToCalendar.ts +13 -13
  111. package/src/composables/useDevice.ts +2 -2
  112. package/src/composables/useExcel.ts +6 -6
  113. package/src/composables/useFormField.ts +5 -9
  114. package/src/composables/usePolling.ts +8 -8
  115. package/src/composables/useSchemaField.ts +53 -38
  116. package/src/composables/useTheme.ts +9 -9
  117. package/src/composables/useValidateFieldValue.ts +2 -2
  118. package/src/directives/pattern.ts +25 -25
  119. package/src/directives/ripple.ts +4 -4
  120. package/src/directives/vResize.ts +6 -6
  121. package/src/plugins/bagel.ts +4 -4
  122. package/src/plugins/useModal.ts +3 -3
  123. package/src/styles/layout.css +7 -1
  124. package/src/utils/BagelFormUtils.ts +7 -7
  125. package/src/utils/calendar/Helpers.ts +8 -8
  126. package/src/utils/calendar/dateUtils.ts +22 -22
  127. package/src/utils/calendar/time.ts +25 -25
  128. package/src/utils/calendar/week.ts +25 -25
  129. package/src/utils/elementUtils.ts +27 -27
  130. package/src/utils/index.ts +22 -22
  131. package/src/utils/sizeParsing.ts +2 -2
  132. package/src/utils/strings.ts +5 -5
  133. package/src/utils/tapDetector.ts +11 -11
  134. package/src/utils/useSearch.ts +29 -29
  135. package/vite.config.ts +1 -1
@@ -14,7 +14,7 @@ export type CalendarProvider = 'google' | 'apple' | 'outlook' | 'outlookcom' | '
14
14
  export function useAddToCalendar(event: CalendarEvent) {
15
15
  // Parse dates if they're strings
16
16
  const parseDate = (date: Date | string): Date => {
17
- return typeof date === 'string' ? new Date(date) : date
17
+ return 'string' === typeof date ? new Date(date) : date
18
18
  }
19
19
 
20
20
  const eventStartDate = parseDate(event.startDate)
@@ -33,7 +33,7 @@ export function useAddToCalendar(event: CalendarEvent) {
33
33
 
34
34
  // Check if location is a URL
35
35
  const isUrl = (text?: string): boolean => {
36
- if (!text || text.length === 0) {
36
+ if (!text || 0 === text.length) {
37
37
  return false
38
38
  }
39
39
  return /^https?:\/\/.+/.test(text.trim())
@@ -77,13 +77,13 @@ export function useAddToCalendar(event: CalendarEvent) {
77
77
  `SUMMARY:${event.title}`,
78
78
  ]
79
79
 
80
- if (event.description && event.description.length > 0) {
80
+ if (event.description && 0 < event.description.length) {
81
81
  // ICS descriptions need special handling of newlines and character limits
82
82
  const description = event.description.replace(/\n/g, '\\n')
83
83
  icsContent.push(`DESCRIPTION:${description}`)
84
84
  }
85
85
 
86
- if (event.location && event.location.length > 0) {
86
+ if (event.location && 0 < event.location.length) {
87
87
  icsContent.push(`LOCATION:${event.location}`)
88
88
  // If location is a URL, also add it as the URL field
89
89
  if (locationIsUrl) {
@@ -104,11 +104,11 @@ export function useAddToCalendar(event: CalendarEvent) {
104
104
  dates: `${formatDateISO(eventStartDate)}/${formatDateISO(eventEndDate)}`,
105
105
  })
106
106
 
107
- if (event.description && event.description.length > 0) {
107
+ if (event.description && 0 < event.description.length) {
108
108
  params.append('details', event.description)
109
109
  }
110
110
 
111
- if (event.location && event.location.length > 0) {
111
+ if (event.location && 0 < event.location.length) {
112
112
  params.append('location', event.location)
113
113
  }
114
114
 
@@ -125,11 +125,11 @@ export function useAddToCalendar(event: CalendarEvent) {
125
125
  enddt: eventEndDate.toISOString(),
126
126
  })
127
127
 
128
- if (event.description && event.description.length > 0) {
128
+ if (event.description && 0 < event.description.length) {
129
129
  params.append('body', event.description)
130
130
  }
131
131
 
132
- if (event.location && event.location.length > 0) {
132
+ if (event.location && 0 < event.location.length) {
133
133
  params.append('location', event.location)
134
134
  }
135
135
 
@@ -146,11 +146,11 @@ export function useAddToCalendar(event: CalendarEvent) {
146
146
  enddt: eventEndDate.toISOString(),
147
147
  })
148
148
 
149
- if (event.description && event.description.length > 0) {
149
+ if (event.description && 0 < event.description.length) {
150
150
  params.append('body', event.description)
151
151
  }
152
152
 
153
- if (event.location && event.location.length > 0) {
153
+ if (event.location && 0 < event.location.length) {
154
154
  params.append('location', event.location)
155
155
  }
156
156
 
@@ -168,11 +168,11 @@ export function useAddToCalendar(event: CalendarEvent) {
168
168
  dur: duration.toString(),
169
169
  })
170
170
 
171
- if (event.description && event.description.length > 0) {
171
+ if (event.description && 0 < event.description.length) {
172
172
  params.append('desc', event.description)
173
173
  }
174
174
 
175
- if (event.location && event.location.length > 0) {
175
+ if (event.location && 0 < event.location.length) {
176
176
  params.append('in_loc', event.location)
177
177
  }
178
178
 
@@ -214,7 +214,7 @@ export function useAddToCalendar(event: CalendarEvent) {
214
214
 
215
215
  // Add to calendar action
216
216
  const addToCalendar = (provider: CalendarProvider) => {
217
- if (provider === 'apple' || provider === 'ics') {
217
+ if ('apple' === provider || 'ics' === provider) {
218
218
  downloadICS()
219
219
  } else {
220
220
  const url = getCalendarUrl(provider)
@@ -2,7 +2,7 @@ import { onMounted, onUnmounted, ref } from 'vue'
2
2
 
3
3
  export function useDevice() {
4
4
  const innerWidth = ref(window.innerWidth)
5
- const isMobile = ref(window.innerWidth < 768)
5
+ const isMobile = ref(768 > window.innerWidth)
6
6
  const scrollY = ref(window.scrollY)
7
7
  const scrollX = ref(window.scrollX)
8
8
  const innerHeight = ref(window.innerHeight)
@@ -20,7 +20,7 @@ export function useDevice() {
20
20
 
21
21
  // Update current values
22
22
  innerWidth.value = window.innerWidth
23
- isMobile.value = window.innerWidth < 768
23
+ isMobile.value = 768 > window.innerWidth
24
24
  scrollY.value = window.scrollY
25
25
  scrollX.value = window.scrollX
26
26
  innerHeight.value = window.innerHeight
@@ -65,7 +65,7 @@ export function useExcel() {
65
65
  const XLSX = await ensureXLSXLoaded()
66
66
 
67
67
  const formattedData = formatData(data, schema)
68
- const headers = schema.length > 0
68
+ const headers = 0 < schema.length
69
69
  ? schema.map((sf) => {
70
70
  const { id, label } = sf as unknown as Field<T>
71
71
  return { v: (label as any) || (id as any), t: 's' }
@@ -73,7 +73,7 @@ export function useExcel() {
73
73
  : []
74
74
  const ws = XLSX.utils.json_to_sheet(formattedData)
75
75
 
76
- if (headers.length > 0) {
76
+ if (0 < headers.length) {
77
77
  XLSX.utils.sheet_add_aoa(ws, [headers.map(h => h.v)], { origin: 'A1' })
78
78
  }
79
79
 
@@ -124,7 +124,7 @@ export function useExcel() {
124
124
  // Read the raw sheet data as arrays
125
125
  const rawSheetData = XLSX.utils.sheet_to_json(worksheet, { header: 1 }) as any[][]
126
126
 
127
- if (rawSheetData.length === 0) {
127
+ if (0 === rawSheetData.length) {
128
128
  return { headers: [], data: [] }
129
129
  }
130
130
 
@@ -196,10 +196,10 @@ export function useExcel() {
196
196
  // Helper function for date detection and conversion
197
197
  function isExcelSerialDate(value: any): boolean {
198
198
  return (
199
- typeof value === 'number'
199
+ 'number' === typeof value
200
200
  && Number.isInteger(value)
201
- && value >= 20000
202
- && value <= 50000
201
+ && 20000 <= value
202
+ && 50000 >= value
203
203
  )
204
204
  }
205
205
 
@@ -12,21 +12,17 @@ export function useFormField<T>(props: {
12
12
 
13
13
  const fieldData = computed({
14
14
  get: () => {
15
- if (!props.fieldID || !formState) return props.modelValue ?? props.field.defaultValue ?? ''
15
+ if (!props.fieldID || !formState) {return props.modelValue ?? props.field.defaultValue ?? ''}
16
16
  const value = formState.getFieldData(props.fieldID)
17
17
  // For nested form containers, default to empty object
18
- if (props.field.$el === 'form' && !value) return {}
19
- // If no value is set yet and a defaultValue exists, write it into form state once
20
- if ((value === undefined || value === null || value === '') && props.field.defaultValue !== undefined) {
21
- formState.updateField(props.fieldID, props.field.defaultValue)
22
- return props.field.defaultValue
23
- }
18
+ if ('form' === props.field.$el && !value) {return {}}
19
+ // Don't auto-restore defaultValue - let user control their content
24
20
  return value ?? ''
25
21
  },
26
22
  set: (val: any) => {
27
- if (!props.fieldID || !formState) return
23
+ if (!props.fieldID || !formState) {return}
28
24
  const currentValue = formState.getFieldData(props.fieldID)
29
- if (JSON.stringify(val) === JSON.stringify(currentValue)) return
25
+ if (JSON.stringify(val) === JSON.stringify(currentValue)) {return}
30
26
 
31
27
  if (props.field.onUpdate) {
32
28
  props.field.onUpdate(val, currentValue)
@@ -25,13 +25,13 @@ export function usePolling(
25
25
  const pollingId = ref<number | null>(null)
26
26
 
27
27
  const isTabActive = () => {
28
- return !pauseInBackground || document.visibilityState === 'visible'
28
+ return !pauseInBackground || 'visible' === document.visibilityState
29
29
  }
30
30
 
31
31
  // Stop polling permanently - cannot be resumed
32
32
  const stopPolling = () => {
33
33
  isPolling.value = false // Permanently set to false
34
- if (pollingId.value !== null) {
34
+ if (null !== pollingId.value) {
35
35
  clearTimeout(pollingId.value)
36
36
  pollingId.value = null
37
37
  }
@@ -39,7 +39,7 @@ export function usePolling(
39
39
 
40
40
  // Pause polling temporarily - can be resumed
41
41
  const pausePolling = () => {
42
- if (pollingId.value !== null) {
42
+ if (null !== pollingId.value) {
43
43
  clearTimeout(pollingId.value)
44
44
  pollingId.value = null
45
45
  }
@@ -49,7 +49,7 @@ export function usePolling(
49
49
  // Start polling with intelligent checks
50
50
  const startPolling = () => {
51
51
  // Clear any existing polling timeout
52
- if (pollingId.value !== null) {
52
+ if (null !== pollingId.value) {
53
53
  clearTimeout(pollingId.value)
54
54
  pollingId.value = null
55
55
  }
@@ -70,13 +70,13 @@ export function usePolling(
70
70
  }
71
71
 
72
72
  const resumePolling = () => {
73
- if (isPolling.value) startPolling()
74
- else console.warn('Cannot resume polling that was stopped')
73
+ if (isPolling.value) {startPolling()}
74
+ else {console.warn('Cannot resume polling that was stopped')}
75
75
  }
76
76
 
77
77
  function updateVisibility() {
78
- if (document.visibilityState === 'visible') {
79
- if (isPolling.value) startPolling()
78
+ if ('visible' === document.visibilityState) {
79
+ if (isPolling.value) {startPolling()}
80
80
  } else if (pauseInBackground) {
81
81
  pausePolling()
82
82
  }
@@ -40,19 +40,19 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
40
40
 
41
41
  // Helper function to render objects recursively
42
42
  function renderObject(obj: T, depth = 0): string {
43
- if (obj === null || obj === undefined) return ''
44
- if (typeof obj !== 'object') return String(obj)
45
- if (Array.isArray(obj)) return obj.map(item => renderObject(item, depth + 1)).join(', ')
43
+ if (null === obj || obj === undefined) {return ''}
44
+ if ('object' !== typeof obj) {return String(obj)}
45
+ if (Array.isArray(obj)) {return obj.map(item => renderObject(item, depth + 1)).join(', ')}
46
46
 
47
47
  // For objects, format as key: value pairs
48
- const indent = depth > 0 ? ' '.repeat(depth) : ''
48
+ const indent = 0 < depth ? ' '.repeat(depth) : ''
49
49
  const nextIndent = ' '.repeat(depth + 1)
50
50
 
51
51
  const entries = Object.entries(obj)
52
- if (entries.length === 0) return '{}'
52
+ if (0 === entries.length) {return '{}'}
53
53
 
54
54
  // For nested objects, format with newlines and indentation
55
- if (depth > 0) {
55
+ if (0 < depth) {
56
56
  return `{\n${entries
57
57
  .map(([key, value]) => `${nextIndent}${key}: ${renderObject(value, depth + 1)}`)
58
58
  .join(',\n')}\n${indent}}`
@@ -61,7 +61,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
61
61
  // For top-level objects, format as a flat list
62
62
  return entries
63
63
  .map(([key, value]) => {
64
- const valueStr = typeof value === 'object' && value !== null
64
+ const valueStr = 'object' === typeof value && null !== value
65
65
  ? renderObject(value, depth + 1)
66
66
  : String(value)
67
67
  return `${key}: ${valueStr}`
@@ -90,18 +90,18 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
90
90
  email: EmailInput
91
91
  }
92
92
 
93
- if (field.$el === 'textarea' && !field.attrs?.multiline) {
93
+ if ('textarea' === field.$el && !field.attrs?.multiline) {
94
94
  field.attrs = { ...field.attrs, multiline: true }
95
95
  }
96
96
 
97
- return typeof field.$el === 'object'
97
+ return 'object' === typeof field.$el
98
98
  ? field.$el
99
99
  : (componentMap[field.$el as keyof typeof componentMap] ?? field.$el ?? 'div')
100
100
  }
101
101
 
102
102
  function renderChild(child: SchemaChild<T, Path<T>>, slots?: BaseBagelField<T, Path<T>>['slots']) {
103
- if (typeof child === 'string') return child
104
- if (isVNode(child)) return child
103
+ if ('string' === typeof child) {return child}
104
+ if (isVNode(child)) {return child}
105
105
  return renderField(
106
106
  child as BaseBagelField<T, Path<T>>,
107
107
  slots
@@ -113,14 +113,14 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
113
113
  slots?: BaseBagelField<T, Path<T>>['slots']
114
114
  ): VNode | undefined {
115
115
  const Component = getComponent(field as Field<T>)
116
- if (!Component) return
116
+ if (!Component) {return}
117
117
 
118
118
  const rowData = (getFormData?.() || {}) as T | undefined
119
119
 
120
120
  // Check vIf condition first
121
121
  const condition = field.vIf ?? field['v-if']
122
122
  if (condition !== undefined) {
123
- if (typeof condition === 'function') {
123
+ if ('function' === typeof condition) {
124
124
  // Compute currentValue for the vIf check
125
125
  const vIfCurrentValue = field.id
126
126
  ? ('get' in (rowData || {})
@@ -134,7 +134,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
134
134
  if (!vIfResult) {
135
135
  return
136
136
  }
137
- } else if (typeof condition === 'string') {
137
+ } else if ('string' === typeof condition) {
138
138
  if (!getNestedValue(rowData, condition)) {
139
139
  return
140
140
  }
@@ -156,6 +156,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
156
156
  label,
157
157
  placeholder,
158
158
  disabled,
159
+ defaultValue,
159
160
  ...fieldProps
160
161
  } = field
161
162
 
@@ -177,9 +178,9 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
177
178
  const boundFieldProps = bindAttrs(fieldProps as Attributes<T, Path<T>> | undefined, currentValue, rowData)
178
179
 
179
180
  // Check if this component should receive value as slot
180
- const isSlotValueComponent = typeof Component === 'string' && SLOT_VALUE_COMPONENTS.has(Component)
181
+ const isSlotValueComponent = 'string' === typeof Component && SLOT_VALUE_COMPONENTS.has(Component)
181
182
  // Check if this component should receive value as src
182
- const isSrcValueComponent = typeof Component === 'string' && SRC_VALUE_COMPONENTS.has(Component)
183
+ const isSrcValueComponent = 'string' === typeof Component && SRC_VALUE_COMPONENTS.has(Component)
183
184
 
184
185
  const props: { [key: string]: any } = {
185
186
  ...boundFieldProps,
@@ -191,10 +192,24 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
191
192
  id,
192
193
  getFormData,
193
194
  onUpdate,
195
+ defaultValue,
196
+ }
197
+
198
+ // Special handling for FieldArray component to pass attrs.schema as schema prop
199
+ if (Component === FieldArray && field.attrs?.schema) {
200
+ props.schema = field.attrs.schema
201
+ }
202
+ // Special handling for FieldArray component to pass attrs.type as type prop
203
+ if (Component === FieldArray && field.attrs?.type) {
204
+ props.type = field.attrs.type
205
+ }
206
+ // Special handling for FieldArray component to pass collapsed prop
207
+ if (Component === FieldArray && 'collapsed' in field) {
208
+ props.collapsed = (field as any).collapsed
194
209
  }
195
210
 
196
211
  // Wire top-level onClick with conditional args
197
- if (typeof (field as any).onClick === 'function') {
212
+ if ('function' === typeof (field as any).onClick) {
198
213
  const original = (field as any).onClick as (val?: any, row?: T) => void
199
214
  props.onClick = () => {
200
215
  if (id) {
@@ -206,7 +221,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
206
221
  }
207
222
 
208
223
  // For form mode, always use the original value for modelValue
209
- if (mode === 'form') {
224
+ if ('form' === mode) {
210
225
  props.modelValue = currentValue
211
226
  props['onUpdate:modelValue'] = (value: any) => {
212
227
  onUpdateModelValue?.(field, value)
@@ -233,7 +248,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
233
248
  if (field.options) {
234
249
  if (Array.isArray(field.options)) {
235
250
  props.options = field.options
236
- } else if (typeof field.options === 'function') {
251
+ } else if ('function' === typeof field.options) {
237
252
  const fn = field.options as any
238
253
  // Component-aware mapping
239
254
  if (Component === SelectInput) {
@@ -241,18 +256,18 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
241
256
  const row = getFormData?.()
242
257
  const val = currentValue
243
258
  // If author expects (query) only, call directly
244
- if (typeof fn === 'function' && fn.length === 1) {
259
+ if ('function' === typeof fn && 1 === fn.length) {
245
260
  return fn(query)
246
261
  }
247
262
  // If author expects (query, val, row), pass it directly
248
- if (typeof fn === 'function' && fn.length >= 3) {
263
+ if ('function' === typeof fn && 3 <= fn.length) {
249
264
  return fn(query, val, row)
250
265
  }
251
266
  // Otherwise evaluate (val,row) → array | (query)=>Promise | Promise
252
267
  const out = fn(val, row)
253
- if (Array.isArray(out)) return out
254
- if (typeof out === 'function') return out(query)
255
- if (out && typeof out.then === 'function') return out
268
+ if (Array.isArray(out)) {return out}
269
+ if ('function' === typeof out) {return out(query)}
270
+ if (out && 'function' === typeof out.then) {return out}
256
271
  return []
257
272
  }
258
273
  } else {
@@ -261,10 +276,10 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
261
276
  const row = getFormData?.()
262
277
  const val = currentValue
263
278
  const out = fn(val, row)
264
- if (Array.isArray(out)) return out
265
- if (typeof out === 'function') return await out('')
266
- if (out && typeof out.then === 'function') return await out
267
- if (fn.length >= 3) return await fn('', val, row)
279
+ if (Array.isArray(out)) {return out}
280
+ if ('function' === typeof out) {return await out('')}
281
+ if (out && 'function' === typeof out.then) {return await out}
282
+ if (3 <= fn.length) {return await fn('', val, row)}
268
283
  return []
269
284
  }
270
285
  }
@@ -278,10 +293,10 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
278
293
  const boundAttrs = bindAttrs(field.attrs, currentValue, rowData)
279
294
  Object.entries(boundAttrs).forEach(([key, value]) => {
280
295
  // Skip $el as it's not a DOM attribute
281
- if (key === '$el') return
296
+ if ('$el' === key) {return}
282
297
 
283
- if (typeof value === 'function') {
284
- if (key === 'onClick') {
298
+ if ('function' === typeof value) {
299
+ if ('onClick' === key) {
285
300
  const original = value as (val?: any, row?: T) => void
286
301
  props.onClick = () => {
287
302
  if (id) {
@@ -309,7 +324,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
309
324
  const componentSlots: Parameters<typeof h>[1] = {}
310
325
 
311
326
  // Add default slot if there are children
312
- if (children && children.length > 0) {
327
+ if (children && 0 < children.length) {
313
328
  componentSlots.default = () => children
314
329
  .map(child => renderChild(child, slots))
315
330
  .filter(Boolean) // Filter out null results from vIf
@@ -327,7 +342,7 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
327
342
  if (Array.isArray(slot)) {
328
343
  // Handle BglFormSchemaT array
329
344
  return slot.map((schemaField) => {
330
- if (typeof schemaField === 'function') {
345
+ if ('function' === typeof schemaField) {
331
346
  // Handle function slot
332
347
  const slotFn = schemaField
333
348
  return slotFn({ row: rowData, field })
@@ -354,19 +369,19 @@ export function useSchemaField<T extends { [key: string]: any }>(optns: UseSchem
354
369
  // ? (slots[field.id])({ row: rowData, field })
355
370
  // : undefined
356
371
 
357
- if (mode === 'preview') {
372
+ if ('preview' === mode) {
358
373
  // Skip rendering if value is unset and includeUnset is false
359
- if (!includeUnset && (transformedValue === undefined || transformedValue === null
360
- || (typeof transformedValue === 'string' && transformedValue.length === 0))) {
374
+ if (!includeUnset && (transformedValue === undefined || null === transformedValue
375
+ || ('string' === typeof transformedValue && 0 === transformedValue.length))) {
361
376
  return
362
377
  }
363
378
 
364
379
  return h('div', { class: 'preview-field' }, [
365
380
  h('div', { class: 'field-label' }, `${field.label || keyToLabel(field.id || '')}:`),
366
381
  h('div', { class: 'field-value' }, [
367
- slotContent || (typeof field.$el === 'object'
382
+ slotContent || ('object' === typeof field.$el
368
383
  ? h(Component as any, props, componentSlots)
369
- : typeof transformedValue === 'object' && transformedValue !== null
384
+ : 'object' === typeof transformedValue && null !== transformedValue
370
385
  ? h('pre', {
371
386
  style: 'margin: 0; white-space: pre-wrap; font-family: inherit; font-size: inherit;'
372
387
  }, renderObject(transformedValue))
@@ -50,17 +50,17 @@ function applyTheme(themeValue: string) {
50
50
 
51
51
  // Remove all theme classes
52
52
  themeOptions.value.forEach((t) => {
53
- if (t.class !== 'system') {
53
+ if ('system' !== t.class) {
54
54
  root.classList.remove(t.class)
55
55
  }
56
56
  })
57
57
 
58
58
  // Handle system theme
59
- if (themeValue === 'system') {
59
+ if ('system' === themeValue) {
60
60
  const systemIsDark = getSystemPrefersDark()
61
61
  isDark.value = systemIsDark
62
- const darkTheme = themeOptions.value.find(t => t.value === 'dark')
63
- const lightTheme = themeOptions.value.find(t => t.value === 'light')
62
+ const darkTheme = themeOptions.value.find(t => 'dark' === t.value)
63
+ const lightTheme = themeOptions.value.find(t => 'light' === t.value)
64
64
  const themeToApply = systemIsDark ? darkTheme : lightTheme
65
65
  if (themeToApply) {
66
66
  root.classList.add(themeToApply.class)
@@ -77,9 +77,9 @@ function applyTheme(themeValue: string) {
77
77
 
78
78
  function toggleTheme() {
79
79
  // Get all non-system themes
80
- const cyclableThemes = themeOptions.value.filter(t => t.value !== 'system')
80
+ const cyclableThemes = themeOptions.value.filter(t => 'system' !== t.value)
81
81
 
82
- if (cyclableThemes.length === 0) return
82
+ if (0 === cyclableThemes.length) {return}
83
83
 
84
84
  const currentIndex = cyclableThemes.findIndex(t => t.value === colorMode.value)
85
85
  const nextIndex = (currentIndex + 1) % cyclableThemes.length
@@ -91,8 +91,8 @@ function addTheme(theme: ThemeOption) {
91
91
  const exists = themeOptions.value.some(t => t.value === theme.value)
92
92
  if (!exists) {
93
93
  // Add before 'system' option
94
- const systemIndex = themeOptions.value.findIndex(t => t.value === 'system')
95
- if (systemIndex > -1) {
94
+ const systemIndex = themeOptions.value.findIndex(t => 'system' === t.value)
95
+ if (-1 < systemIndex) {
96
96
  themeOptions.value.splice(systemIndex, 0, theme)
97
97
  } else {
98
98
  themeOptions.value.push(theme)
@@ -130,7 +130,7 @@ export function useTheme() {
130
130
  // React to system changes when in "system" mode
131
131
  const mq = window.matchMedia('(prefers-color-scheme: dark)')
132
132
  const handler = (e: MediaQueryListEvent) => {
133
- if (colorMode.value === 'system') {
133
+ if ('system' === colorMode.value) {
134
134
  applyTheme('system')
135
135
  }
136
136
  }
@@ -12,9 +12,9 @@ export function useValidateFieldValue(
12
12
  inputVal,
13
13
  (newVal, oldVal) => {
14
14
  getInput?.()?.setCustomValidity('')
15
- if (!validateFn || newVal === oldVal || !newVal) return
15
+ if (!validateFn || newVal === oldVal || !newVal) {return}
16
16
  const isValid = validateFn(newVal, getFormData?.())
17
- if (typeof isValid === 'string') getInput?.()?.setCustomValidity(isValid)
17
+ if ('string' === typeof isValid) {getInput?.()?.setCustomValidity(isValid)}
18
18
  },
19
19
  { debounce: 500 },
20
20
  )