@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
@@ -10,12 +10,12 @@ import type {
10
10
  Path
11
11
  } from '@bagelink/vue'
12
12
  import type { MaybeRefOrGetter } from 'vue'
13
- import { BagelForm, Btn, Loading, Icon } from '@bagelink/vue'
14
- import { ref, computed, watch, toValue } from 'vue'
13
+ import { BagelForm, Btn, Loading, Icon, Card } from '@bagelink/vue'
14
+ import { ref, computed, watch, toValue, onMounted } from 'vue'
15
15
 
16
16
  export interface FieldArrayProps<T, P extends Path<T>> {
17
17
  el?: any
18
- id: string
18
+ id?: string
19
19
  label?: string
20
20
  placeholder?: string
21
21
  children?: Field<T>[]
@@ -25,13 +25,14 @@ export interface FieldArrayProps<T, P extends Path<T>> {
25
25
  disabled?: boolean
26
26
  helptext?: string
27
27
  options?: BagelFieldOptions<T, P>
28
- defaultValue?: any
28
+ defaultValue?: T[]
29
29
  add?: boolean
30
30
  delete?: boolean
31
+ collapsed?: boolean
31
32
  transform?: (value: T) => T
32
33
  schema?: MaybeRefOrGetter<BglFormSchemaT<T>>
33
- modelValue: T[]
34
- type?: 'object' | 'number' | 'text'
34
+ modelValue?: T[]
35
+ type?: 'object' | 'number' | 'text' | 'array'
35
36
  }
36
37
 
37
38
  export interface PrimitiveArrFieldT extends BaseBagelField<{ value: string }, 'value'> {
@@ -45,6 +46,7 @@ const props = withDefaults(
45
46
  add: true,
46
47
  el: 'div',
47
48
  type: 'object',
49
+ collapsed: false,
48
50
  }
49
51
  )
50
52
 
@@ -56,27 +58,93 @@ const BagelFormFA = BagelForm<T, P>
56
58
  const minimizedItems = ref<boolean[]>([])
57
59
  const internalData = ref<any[]>(props.modelValue || [])
58
60
  const schemaState = ref<'loading' | 'loaded' | 'error'>('loaded')
61
+ let lastEmittedValue = '' // Event handlers state
59
62
 
60
63
  // Generate schema for primitive types
61
64
  const primitiveSchema = computed<PrimitiveArrFieldT[]>(() => {
62
- if (props.type === 'text') {
65
+ if ('text' === props.type) {
63
66
  return [{ id: 'value', type: 'text', label: '', $el: 'text' }]
64
- } else if (props.type === 'number') {
67
+ }if (props.type === 'number') {
65
68
  return [{ id: 'value', type: 'number', label: '', $el: 'number' }]
66
69
  }
67
70
  return []
68
71
  })
69
72
 
70
- const resolvedSchemaData = $computed(() => {
71
- if (props.type !== 'object') return primitiveSchema.value as BglFormSchemaT<T>
73
+ const resolvedSchemaData = computed(() => {
74
+ // Handle 'array' type as equivalent to 'object' type
75
+ const isObjectType = 'object' === props.type || 'array' === props.type
72
76
 
73
- return toValue(props.schema)
74
- })
77
+ if (!isObjectType) {return primitiveSchema.value as BglFormSchemaT<T>}
78
+
79
+ // Use children prop first, then schema prop, then attrs.schema
80
+ const attrsSchema = props.attrs?.schema !== undefined ? toValue(props.attrs.schema) : null
81
+ const schemaToUse = props.children || toValue(props.schema) || attrsSchema
82
+
83
+ // If no schema but we have defaultValue, try to infer schema from first item
84
+ const noSchema = null === schemaToUse || schemaToUse === undefined
85
+ || (Array.isArray(schemaToUse) && 0 === schemaToUse.length)
86
+ const hasDefaultValue = props.defaultValue !== undefined
87
+ && null !== props.defaultValue
88
+ && 0 < props.defaultValue.length
75
89
 
76
- // Watch for external changes to modelValue
90
+ // Don't infer schema from defaultValue - this causes unwanted restoration
91
+ // Let the component work with empty arrays
92
+ return schemaToUse as BglFormSchemaT<T>
93
+ })// Watch for external changes to modelValue - simple and straightforward
77
94
  watch(() => props.modelValue, (newValue) => {
78
- internalData.value = newValue || []
79
- }, { deep: true })
95
+ // Simply sync with external changes, no automatic defaultValue restoration
96
+ if (newValue && Array.isArray(newValue)) {
97
+ internalData.value = [...newValue]
98
+ } else {
99
+ internalData.value = []
100
+ }
101
+ }, { deep: true, immediate: false })
102
+
103
+ // Watch for changes to internalData length to sync minimizedItems
104
+ watch(() => internalData.value.length, (newLength) => {
105
+ // Resize minimizedItems array to match internalData length
106
+ if (minimizedItems.value.length !== newLength) {
107
+ // If array grew, add new items with collapsed state
108
+ if (minimizedItems.value.length < newLength) {
109
+ const itemsToAdd = newLength - minimizedItems.value.length
110
+ for (let i = 0; i < itemsToAdd; i++) {
111
+ minimizedItems.value.push(props.collapsed || false)
112
+ }
113
+ } else {
114
+ // If array shrank, remove excess items
115
+ minimizedItems.value = minimizedItems.value.slice(0, newLength)
116
+ }
117
+ }
118
+ })
119
+
120
+ // Initialize with existing data or defaultValue on mount - only once!
121
+ onMounted(() => {
122
+ // If no modelValue provided, use defaultValue as initial data (one time only)
123
+ if (!props.modelValue || 0 === props.modelValue.length) {
124
+ if (props.defaultValue && 0 < props.defaultValue.length) {
125
+ internalData.value = [...props.defaultValue]
126
+ emitValue() // This will set the initial value and then it becomes "regular" data
127
+ }
128
+ }
129
+
130
+ // Initialize minimized state based on collapsed prop
131
+ if (props.collapsed) {
132
+ minimizedItems.value = Array.from({ length: internalData.value.length }, () => true)
133
+ } else {
134
+ minimizedItems.value = Array.from({ length: internalData.value.length }, () => false)
135
+ }
136
+ })
137
+
138
+ // Function to load default values (explicit user action)
139
+ function loadDefaults() {
140
+ if (props.defaultValue && 0 < props.defaultValue.length) {
141
+ internalData.value = [...props.defaultValue]
142
+ emitValue()
143
+ } else {
144
+ // If no defaultValue in props, add a single empty item
145
+ addItem()
146
+ }
147
+ }
80
148
 
81
149
  // Resolve schema
82
150
  // async function resolveSchema() {
@@ -120,23 +188,43 @@ watch(() => props.modelValue, (newValue) => {
120
188
  // onMounted(resolveSchema)
121
189
 
122
190
  // Event handlers
191
+
123
192
  function emitValue() {
124
- emit('update:modelValue', internalData.value)
193
+ // Only emit if the value has actually changed to prevent recursive updates
194
+ const currentValue = JSON.stringify(props.modelValue || [])
195
+ const newValue = JSON.stringify(internalData.value || [])
196
+
197
+ // Double-check against last emitted value to prevent loops
198
+ if (currentValue !== newValue && lastEmittedValue !== newValue) {
199
+ lastEmittedValue = newValue
200
+ emit('update:modelValue', internalData.value)
201
+ // Reset after a short delay to allow for new changes
202
+ setTimeout(() => {
203
+ lastEmittedValue = ''
204
+ }, 50)
205
+ }
125
206
  }
126
207
 
127
208
  function deleteItem(i: number) {
128
209
  internalData.value.splice(i, 1)
210
+ minimizedItems.value.splice(i, 1)
129
211
  emitValue()
130
212
  }
131
213
 
132
214
  function addItem() {
133
215
  // Add appropriate default value based on type
134
- const defaultValues = {
216
+ const defaultValues: { [key: string]: any } = {
135
217
  text: '',
136
218
  number: 0,
137
- object: {}
219
+ object: {},
220
+ array: {}
138
221
  }
139
- internalData.value.push(defaultValues[props.type])
222
+ const defaultValue = defaultValues[props.type]
223
+ internalData.value.push(defaultValue !== undefined ? defaultValue : {})
224
+
225
+ // Add minimized state for new item - always open (false) when newly added
226
+ minimizedItems.value.push(false)
227
+
140
228
  emitValue()
141
229
  }
142
230
 
@@ -146,8 +234,8 @@ function toggleMinimized(index: number) {
146
234
 
147
235
  function updateItem(index: number, value: any) {
148
236
  // Handle primitive types by extracting the value property
149
- if (props.type === 'text' || props.type === 'number') {
150
- internalData.value[index] = props.type === 'number' ? Number(value.value) : value.value
237
+ if ('text' === props.type || 'number' === props.type) {
238
+ internalData.value[index] = 'number' === props.type ? Number(value.value) : value.value
151
239
  } else {
152
240
  internalData.value[index] = value
153
241
  }
@@ -155,14 +243,25 @@ function updateItem(index: number, value: any) {
155
243
  }
156
244
 
157
245
  // Computed properties for rendering
158
- const isPrimitiveType = computed(() => props.type === 'text' || props.type === 'number')
159
- const canRenderItems = computed(
160
- () => isPrimitiveType.value || (
161
- props.type === 'object' && Number(resolvedSchemaData?.length) > 0
162
- )
163
- )
246
+ const isPrimitiveType = computed(() => 'text' === props.type || 'number' === props.type)
247
+ const canRenderItems = computed(() => {
248
+ const schemaData = resolvedSchemaData.value
249
+ const hasValidSchema = (Array.isArray(schemaData) && 0 < schemaData.length)
250
+ || (props.children && 0 < props.children.length)
251
+ const hasDefaultValue = props.defaultValue && 0 < props.defaultValue.length
252
+
253
+ // For primitive types or when we have schema or defaultValue
254
+ const isObjectType = 'object' === props.type || 'array' === props.type
255
+ const shouldRender = isPrimitiveType.value
256
+ || (isObjectType && (true === hasValidSchema || true === hasDefaultValue))
257
+ return shouldRender
258
+ })
164
259
  const showMinimizeButton = computed(() => {
165
- return Number(resolvedSchemaData?.length) > 2 || resolvedSchemaData?.some(schema => schema.$el === 'richtext')
260
+ const schemaData = resolvedSchemaData.value
261
+ const hasLongSchema = Array.isArray(schemaData) && 2 < schemaData.length
262
+ const hasRichText = Array.isArray(schemaData)
263
+ && schemaData.some((schema: any) => 'richtext' === schema.$el)
264
+ return hasLongSchema || hasRichText
166
265
  })
167
266
  </script>
168
267
 
@@ -172,7 +271,7 @@ const showMinimizeButton = computed(() => {
172
271
  <p v-if="label" class="label mb-05">
173
272
  {{ label }}
174
273
  </p>
175
- <div class="ps-025 border-start mb-05">
274
+ <div class="ps-025 mb-05">
176
275
  <!-- Loading/Error States -->
177
276
  <div v-if="schemaState !== 'loaded'" class="flex-center h-300px">
178
277
  <Loading v-if="schemaState === 'loading'" />
@@ -180,54 +279,50 @@ const showMinimizeButton = computed(() => {
180
279
  </div>
181
280
 
182
281
  <!-- No Schema Available -->
183
- <div v-else-if="!canRenderItems" class="py-1">
282
+ <Card v-else-if="!canRenderItems" class="py-1 border mb-05">
184
283
  <p class="opacity-7">
185
284
  No schema available
186
285
  </p>
187
- </div>
286
+ </Card>
188
287
 
189
288
  <!-- Items Rendering -->
190
289
  <template v-else>
290
+ <!-- Empty Array Message -->
291
+ <Card v-if="internalData.length === 0" class="py-1 border mb-05">
292
+ <p class="opacity-7 txt-center txt14">
293
+ No {{ label?.toLowerCase() || 'items' }} added yet
294
+ </p>
295
+ <!-- Load defaults button if defaultValue exists -->
296
+ <Btn v-if="props.defaultValue && props.defaultValue.length > 0" thin color="primary" class="txt12 mb-05" @click="loadDefaults">
297
+ Load Default {{ label || 'Items' }}
298
+ </Btn>
299
+ </Card>
300
+
191
301
  <!-- Array Items -->
192
302
  <div
193
303
  v-for="(item, i) in internalData"
194
304
  :key="i"
195
305
  outline
196
306
  thin
197
- class="mb-05 itemBox transition ps-05 pb-025 pt-025 radius-05 gap-05 overflow-hidden"
307
+ class="mb-05 itemBox transition radius-05 overflow-hidden txt12 border"
308
+ style="--input-font-size: 12px"
198
309
  :class="{ minimized: minimizedItems[i] }"
199
310
  >
200
- <!-- Minimized View -->
201
- <p v-if="minimizedItems[i]" class="minimizedText txt14 p-025 opacity-7">
202
- {{ label }} {{ i + 1 }}
203
- </p>
311
+ <div>
312
+ <!-- Minimized View -->
313
+ <div class="flex pointer">
314
+ <p class="minimizedText txt12 p-05 opacity-7 flex-grow-2" @click="toggleMinimized(i)">
315
+ {{ label }} {{ i + 1 }}
316
+ </p>
317
+ <Btn v-if="showMinimizeButton" class="rotate-180 txt10 opacity-7 p-025" flat thin icon="keyboard_arrow_down" @click="toggleMinimized(i)" />
318
+ </div>
204
319
 
205
- <!-- Form View -->
206
- <BagelFormFA
207
- v-else
208
- :model-value="isPrimitiveType ? { value: item } : item"
209
- :schema="resolvedSchemaData"
210
- @update:model-value="val => updateItem(i, val)"
211
- />
212
-
213
- <!-- Controls -->
214
- <div class="bg-gray-80 -my-05 px-025 pt-065 pb-05 txt-center space-between flex column">
215
- <Btn
216
- v-if="showMinimizeButton"
217
- class="block rotate-180 txt10 opacity-7 p-025"
218
- flat
219
- thin
220
- icon="keyboard_arrow_down"
221
- @click="toggleMinimized(i)"
222
- />
223
- <Btn
224
- v-if="props.delete"
225
- icon="delete"
226
- class="txt10 opacity-7"
227
- thin
228
- flat
229
- @click="deleteItem(i)"
320
+ <!-- Form View -->
321
+ <BagelFormFA
322
+ v-if="!minimizedItems[i]" :model-value="isPrimitiveType ? { value: item } : item" :schema="resolvedSchemaData" class="bginputbg p-05 grid gap-05"
323
+ @update:model-value="val => updateItem(i, val)"
230
324
  />
325
+ <Btn v-if="props.delete" icon="delete" class="txt10 opacity-7" thin flat @click="deleteItem(i)" />
231
326
  </div>
232
327
  </div>
233
328
 
@@ -242,25 +337,34 @@ const showMinimizeButton = computed(() => {
242
337
 
243
338
  <style>
244
339
  .minimized {
245
- height: 2.4rem;
340
+ height: 2.3rem;
246
341
  overflow: hidden;
342
+ border-color: transparent !important;
343
+
247
344
  }
345
+
248
346
  .minimizedText {
249
- display: none;
347
+ /* display: none; */
348
+ padding-top: 1rem !important;
250
349
  }
350
+
251
351
  .minimized .minimizedText {
252
352
  display: block;
253
353
  }
354
+
254
355
  .minimized .rotate-180 {
255
356
  transform: rotate(0deg);
256
357
  }
358
+
257
359
  .itemBox {
258
- background: var(--input-bg);
259
- grid-template-columns: 1fr auto;
260
- display: grid;
360
+ background: var(--btn-bg);
261
361
  --label-font-size: 0.6rem;
262
362
  --input-height: 30px;
263
- --input-font-size: 14px;
363
+ --input-font-size: 7px;
364
+ }
365
+
366
+ .bginputbg {
367
+ background: var(--input-bg);
264
368
  }
265
369
 
266
370
  .pt-065 {
@@ -273,10 +377,16 @@ const showMinimizeButton = computed(() => {
273
377
  .itemBox .custom-select .input {
274
378
  background: var(--bgl-white) !important;
275
379
  }
380
+
276
381
  .itemBox .code-editor-wrap textarea {
277
382
  background: transparent !important;
278
383
  }
384
+
279
385
  .itemBox .bagel-input {
280
386
  margin-bottom: 0.15rem !important;
281
387
  }
388
+
389
+ .itemBox .richtext-editor-content {
390
+ font-size: 1px !important;
391
+ }
282
392
  </style>
@@ -17,7 +17,8 @@ const inputId = $computed(() => id || Math.random().toString(36).slice(7))
17
17
  const checked = defineModel<T>('modelValue', { default: undefined })
18
18
 
19
19
  onMounted(() => {
20
- if (checked.value === undefined) checked.value = defaultValue as T
20
+ // Don't auto-restore defaultValue - let user control their own content
21
+ // if (checked.value === undefined) checked.value = defaultValue as T
21
22
  })
22
23
  </script>
23
24
 
@@ -43,7 +43,7 @@ function handleInput(e: Event) {
43
43
  }
44
44
 
45
45
  function handleTab(event: KeyboardEvent) {
46
- if (event.key !== 'Tab') return
46
+ if ('Tab' !== event.key) {return}
47
47
 
48
48
  event.preventDefault()
49
49
  const target = event.target as HTMLTextAreaElement
@@ -38,7 +38,7 @@ const format = {
38
38
  for (let i = 0; i < jsCode.length; i++) {
39
39
  const char = jsCode[i]
40
40
  const nextChar = jsCode[i + 1]
41
- if (char === '"' || char === '\'' || char === '`') {
41
+ if ('"' === char || '\'' === char || '`' === char) {
42
42
  formatted += char
43
43
  if (inString.length && inString === char) {
44
44
  inString = ''
@@ -51,25 +51,25 @@ const format = {
51
51
  formatted += char
52
52
  continue
53
53
  }
54
- if (char === '{' || char === '[') {
54
+ if ('{' === char || '[' === char) {
55
55
  formatted += `${char}\n${tab.repeat(++level)}`
56
56
  continue
57
57
  }
58
- if (char === '}' || char === ']') {
58
+ if ('}' === char || ']' === char) {
59
59
  formatted += `\n${tab.repeat(--level)}${char}`
60
60
  continue
61
61
  }
62
- if (char === ';' || char === ',') {
62
+ if (';' === char || ',' === char) {
63
63
  formatted += `${char}\n${tab.repeat(level)}`
64
64
  continue
65
65
  }
66
- if (char === '\n') {
66
+ if ('\n' === char) {
67
67
  formatted += `\n${tab.repeat(level)}`
68
68
  continue
69
69
  }
70
70
  if (
71
- (char === ')' && nextChar === '{')
72
- || (char === ')' && nextChar === ' ')
71
+ (')' === char && '{' === nextChar)
72
+ || (')' === char && ' ' === nextChar)
73
73
  ) {
74
74
  formatted += `${char}\n${tab.repeat(level)}`
75
75
  continue
@@ -14,8 +14,8 @@ export function useHighlight(theme: HighlightTheme = 'dark') {
14
14
  const currentTheme = ref<HighlightTheme>(theme)
15
15
 
16
16
  const normalizeTheme = (t: HighlightTheme): HighlightTheme => {
17
- if (t === 'dark') return 'atom-one-dark'
18
- if (t === 'light') return 'atom-one-light'
17
+ if ('dark' === t) {return 'atom-one-dark'}
18
+ if ('light' === t) {return 'atom-one-light'}
19
19
  return t
20
20
  }
21
21
 
@@ -24,14 +24,14 @@ export function useHighlight(theme: HighlightTheme = 'dark') {
24
24
  const removeExistingThemeLinks = () => {
25
25
  document.querySelectorAll('link[rel="stylesheet"]').forEach((link) => {
26
26
  if (link instanceof HTMLLinkElement && link.href.includes('/styles/')) {
27
- if (link.href.includes('highlight.js')) link.parentElement?.removeChild(link)
27
+ if (link.href.includes('highlight.js')) {link.parentElement?.removeChild(link)}
28
28
  }
29
29
  })
30
30
  }
31
31
 
32
32
  const setTheme = async (theme: HighlightTheme) => {
33
33
  const next = normalizeTheme(theme)
34
- if (next === currentTheme.value) return
34
+ if (next === currentTheme.value) {return}
35
35
  try {
36
36
  removeExistingThemeLinks()
37
37
  const url = getThemeCssUrl(next)
@@ -48,7 +48,7 @@ export function useHighlight(theme: HighlightTheme = 'dark') {
48
48
  }
49
49
 
50
50
  const loadHighlight = async () => {
51
- if (loaded.value) return
51
+ if (loaded.value) {return}
52
52
 
53
53
  try {
54
54
  // Load highlight.js
@@ -80,7 +80,7 @@ export function useHighlight(theme: HighlightTheme = 'dark') {
80
80
  }
81
81
 
82
82
  const highlightCode = (code: string, language?: string, autodetect = true, ignoreIllegals = true) => {
83
- if (!hljs.value) return escapeHtml(code)
83
+ if (!hljs.value) {return escapeHtml(code)}
84
84
 
85
85
  try {
86
86
  const lang = language || ''
@@ -45,7 +45,7 @@ const isOpen = ref(false)
45
45
  // Date formatting composable
46
46
  function useFormatting() {
47
47
  const formatDisplayDate = (date: Date | string | undefined): string => {
48
- if (!date) return ''
48
+ if (!date) {return ''}
49
49
  return formatDate(date, { fmt: props.enableTime ? 'DD.MM.YY HH:mm' : 'DD.MM.YY' })
50
50
  }
51
51
 
@@ -58,7 +58,7 @@ function useFormatting() {
58
58
 
59
59
  // Try DD/MM/YYYY format
60
60
  const parts = input.split(/[/.-]/)
61
- if (parts.length === 3) {
61
+ if (3 === parts.length) {
62
62
  const [day, month, year] = parts.map(p => Number.parseInt(p, 10))
63
63
  if (!Number.isNaN(day) && !Number.isNaN(month) && !Number.isNaN(year)) {
64
64
  const parsedDate = new Date(year, month - 1, day)
@@ -79,12 +79,12 @@ function useFormatting() {
79
79
  if (props.enableTime) {
80
80
  // Keep the time when time is enabled
81
81
  return date.toISOString()
82
- } else {
82
+ }
83
83
  // Normalize to midnight to emit exact date without time for server compatibility
84
84
  const normalizedDate = new Date(date)
85
85
  normalizedDate.setHours(0, 0, 0, 0)
86
86
  return normalizedDate.toISOString().split('T')[0]
87
- }
87
+
88
88
  }
89
89
 
90
90
  return {
@@ -123,9 +123,9 @@ function useInputHandling() {
123
123
  }
124
124
 
125
125
  const handleKeydown = (event: KeyboardEvent) => {
126
- if (event.key === 'Escape') {
126
+ if ('Escape' === event.key) {
127
127
  isOpen.value = false
128
- } else if (event.key === 'Enter' && inputValue.value) {
128
+ } else if ('Enter' === event.key && inputValue.value) {
129
129
  const date = parseUserInput(inputValue.value)
130
130
  if (date) {
131
131
  selectedDate.value = normalizeDate(date)
@@ -40,34 +40,34 @@ const time = new Time(props.firstDayOfWeek, props.locale)
40
40
 
41
41
  // Parse a date string or object into a Date object
42
42
  function parseDate(value: string | Date | undefined): Date | null {
43
- if (!value) return null
44
- const date = typeof value === 'string' ? new Date(value) : value
43
+ if (!value) {return null}
44
+ const date = 'string' === typeof value ? new Date(value) : value
45
45
  return Number.isNaN(date.getTime()) ? null : date
46
46
  }
47
47
 
48
48
  // Date validation composable
49
49
  function useDateValidation() {
50
50
  const isDateDisabled = (date: Date | null) => {
51
- if (!date) return true
51
+ if (!date) {return true}
52
52
  const minDate = parseDate(props.min)
53
53
  const maxDate = parseDate(props.max)
54
54
 
55
55
  // Check if date is in min/max range
56
- if (minDate && date < minDate) return true
57
- if (maxDate && date > maxDate) return true
56
+ if (minDate && date < minDate) {return true}
57
+ if (maxDate && date > maxDate) {return true}
58
58
 
59
59
  // Check if date is in the disabled dates array
60
- if (Array.isArray(computedDisabledDates) && computedDisabledDates.length > 0) {
60
+ if (Array.isArray(computedDisabledDates) && 0 < computedDisabledDates.length) {
61
61
  const isInDisabledDates = computedDisabledDates.some((disabledDate) => {
62
62
  const parsedDisabledDate = parseDate(disabledDate)
63
- if (!parsedDisabledDate) return false
63
+ if (!parsedDisabledDate) {return false}
64
64
 
65
65
  // Compare year, month, and day
66
66
  return date.getFullYear() === parsedDisabledDate.getFullYear()
67
67
  && date.getMonth() === parsedDisabledDate.getMonth()
68
68
  && date.getDate() === parsedDisabledDate.getDate()
69
69
  })
70
- if (isInDisabledDates) return true
70
+ if (isInDisabledDates) {return true}
71
71
  }
72
72
 
73
73
  return false
@@ -77,8 +77,8 @@ function useDateValidation() {
77
77
  const minDate = parseDate(props.min)
78
78
  const maxDate = parseDate(props.max)
79
79
 
80
- if (minDate && year < minDate.getFullYear()) return true
81
- if (maxDate && year > maxDate.getFullYear()) return true
80
+ if (minDate && year < minDate.getFullYear()) {return true}
81
+ if (maxDate && year > maxDate.getFullYear()) {return true}
82
82
  return false
83
83
  }
84
84
 
@@ -114,7 +114,7 @@ function useCalendarView() {
114
114
 
115
115
  // Always ensure we have 6 rows (42 days) in our calendar
116
116
  // If we have less than 6 weeks, add extra week(s) from the next month
117
- while (weeksInMonth.length < 6) {
117
+ while (6 > weeksInMonth.length) {
118
118
  const lastWeek = weeksInMonth[weeksInMonth.length - 1]
119
119
  const lastDay = lastWeek[lastWeek.length - 1]
120
120
  const nextDay = new Date(lastDay.getFullYear(), lastDay.getMonth(), lastDay.getDate() + 1)
@@ -163,14 +163,14 @@ function useCalendarView() {
163
163
  })
164
164
 
165
165
  const isSelected = (date: Date | null) => {
166
- if (!date || !selectedDate.value) return false
166
+ if (!date || !selectedDate.value) {return false}
167
167
  return date.getFullYear() === selectedDate.value.getFullYear()
168
168
  && date.getMonth() === selectedDate.value.getMonth()
169
169
  && date.getDate() === selectedDate.value.getDate()
170
170
  }
171
171
 
172
172
  const isToday = (date: Date | null) => {
173
- if (!date) return false
173
+ if (!date) {return false}
174
174
  return time.dateIsToday(date)
175
175
  }
176
176
 
@@ -190,7 +190,7 @@ function useCalendarView() {
190
190
 
191
191
  return computedHighlightedDates.some((highlightedDate) => {
192
192
  const parsedDate = parseDate(highlightedDate)
193
- if (!parsedDate) return false
193
+ if (!parsedDate) {return false}
194
194
 
195
195
  // Compare year, month, and day
196
196
  return date.getFullYear() === parsedDate.getFullYear()
@@ -233,12 +233,12 @@ function useNavigation() {
233
233
  }
234
234
 
235
235
  const previousYear = () => {
236
- const offset = currentView.value === 'months' ? 1 : 21
236
+ const offset = 'months' === currentView.value ? 1 : 21
237
237
  currentMonth.value = new Date(currentMonth.value.getFullYear() - offset, currentMonth.value.getMonth(), 1)
238
238
  }
239
239
 
240
240
  const nextYear = () => {
241
- const offset = currentView.value === 'months' ? 1 : 21
241
+ const offset = 'months' === currentView.value ? 1 : 21
242
242
  currentMonth.value = new Date(currentMonth.value.getFullYear() + offset, currentMonth.value.getMonth(), 1)
243
243
  }
244
244
 
@@ -258,14 +258,14 @@ function useTimeHandling() {
258
258
  const minutes = computed(() => selectedDate.value?.getMinutes() ?? 0)
259
259
 
260
260
  const handleHourInput = (value: number) => {
261
- if (!selectedDate.value) return
261
+ if (!selectedDate.value) {return}
262
262
  const newDate = new Date(selectedDate.value)
263
263
  newDate.setHours(value)
264
264
  emitDateValue(newDate)
265
265
  }
266
266
 
267
267
  const handleMinuteInput = (value: number) => {
268
- if (!selectedDate.value) return
268
+ if (!selectedDate.value) {return}
269
269
  const newDate = new Date(selectedDate.value)
270
270
  newDate.setMinutes(value)
271
271
  emitDateValue(newDate)
@@ -308,7 +308,7 @@ const { hours, minutes, handleHourInput, handleMinuteInput } = useTimeHandling()
308
308
 
309
309
  // Date selection handler
310
310
  function selectDate(date: Date | null) {
311
- if (!date) return
311
+ if (!date) {return}
312
312
 
313
313
  if (props.enableTime) {
314
314
  // Create date with current time values