@bagelink/vue 1.5.17 → 1.5.22

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 (133) 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/calendar/CalendarPopover.vue.d.ts.map +1 -1
  6. package/dist/components/form/BagelForm.vue.d.ts.map +1 -1
  7. package/dist/components/form/FieldArray.vue.d.ts +5 -4
  8. package/dist/components/form/FieldArray.vue.d.ts.map +1 -1
  9. package/dist/components/form/inputs/CheckInput.vue.d.ts.map +1 -1
  10. package/dist/components/form/inputs/RichText/index.vue.d.ts +1 -0
  11. package/dist/components/form/inputs/RichText/index.vue.d.ts.map +1 -1
  12. package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
  13. package/dist/components/form/inputs/ToggleInput.vue.d.ts.map +1 -1
  14. package/dist/components/form/inputs/Upload/UploadInput.vue.d.ts.map +1 -1
  15. package/dist/composables/useFormField.d.ts.map +1 -1
  16. package/dist/composables/useSchemaField.d.ts.map +1 -1
  17. package/dist/index.cjs +17 -14
  18. package/dist/index.mjs +511 -422
  19. package/dist/style.css +1 -1
  20. package/package.json +1 -1
  21. package/src/components/AccordionItem.vue +2 -2
  22. package/src/components/AddToCalendar.vue +1 -1
  23. package/src/components/BglVideo.vue +8 -8
  24. package/src/components/Btn.vue +9 -9
  25. package/src/components/Card.vue +4 -4
  26. package/src/components/Carousel.vue +44 -44
  27. package/src/components/DataPreview.vue +1 -1
  28. package/src/components/DragOver.vue +6 -6
  29. package/src/components/Dropdown.vue +14 -14
  30. package/src/components/Flag.vue +3 -3
  31. package/src/components/Icon/Icon.vue +13 -13
  32. package/src/components/Image.vue +4 -4
  33. package/src/components/ImportData.vue +79 -79
  34. package/src/components/ListItem.vue +7 -7
  35. package/src/components/MapEmbed/Index.vue +6 -6
  36. package/src/components/Modal.vue +10 -10
  37. package/src/components/ModalForm.vue +4 -4
  38. package/src/components/NavBar.vue +2 -2
  39. package/src/components/Pagination.vue +9 -9
  40. package/src/components/Pill.vue +1 -1
  41. package/src/components/Rating.vue +2 -2
  42. package/src/components/Slider.vue +77 -77
  43. package/src/components/Spreadsheet/Index.vue +34 -34
  44. package/src/components/Spreadsheet/SpreadsheetTable.vue +3 -3
  45. package/src/components/Zoomer.vue +28 -28
  46. package/src/components/analytics/BarChart.vue +6 -6
  47. package/src/components/analytics/KpiCard.vue +2 -2
  48. package/src/components/analytics/LineChart.vue +14 -14
  49. package/src/components/analytics/PieChart.vue +11 -11
  50. package/src/components/calendar/CalendarPopover.vue +1 -1
  51. package/src/components/calendar/Index.vue +1 -1
  52. package/src/components/calendar/views/AgendaView.vue +2 -2
  53. package/src/components/calendar/views/DayView.vue +6 -6
  54. package/src/components/calendar/views/MonthView.vue +2 -2
  55. package/src/components/calendar/views/WeekView.vue +18 -18
  56. package/src/components/dataTable/DataTable.vue +3 -3
  57. package/src/components/dataTable/useSorting.ts +1 -1
  58. package/src/components/dataTable/useTableData.ts +15 -15
  59. package/src/components/dataTable/useTableSelection.ts +8 -8
  60. package/src/components/dataTable/useTableVirtualization.ts +1 -1
  61. package/src/components/draggable/useDraggable.ts +42 -42
  62. package/src/components/form/BagelForm.vue +66 -23
  63. package/src/components/form/BglMultiStepForm.vue +18 -18
  64. package/src/components/form/FieldArray.vue +177 -67
  65. package/src/components/form/inputs/CheckInput.vue +2 -1
  66. package/src/components/form/inputs/CodeEditor/Index.vue +1 -1
  67. package/src/components/form/inputs/CodeEditor/format.ts +7 -7
  68. package/src/components/form/inputs/CodeEditor/useHighlight.ts +6 -6
  69. package/src/components/form/inputs/DateInput.vue +6 -6
  70. package/src/components/form/inputs/DatePicker.vue +19 -19
  71. package/src/components/form/inputs/EmailInput.vue +14 -14
  72. package/src/components/form/inputs/NumberInput.vue +6 -6
  73. package/src/components/form/inputs/OTP.vue +3 -3
  74. package/src/components/form/inputs/RadioGroup.vue +1 -1
  75. package/src/components/form/inputs/RadioPillsInput.vue +8 -8
  76. package/src/components/form/inputs/RichText/components/EditorToolbar.vue +10 -10
  77. package/src/components/form/inputs/RichText/components/TableGridSelector.vue +1 -1
  78. package/src/components/form/inputs/RichText/composables/useCommands.ts +1 -1
  79. package/src/components/form/inputs/RichText/composables/useEditor.ts +12 -12
  80. package/src/components/form/inputs/RichText/composables/useEditorKeyboard.ts +1 -1
  81. package/src/components/form/inputs/RichText/index.vue +143 -134
  82. package/src/components/form/inputs/RichText/utils/commands.ts +69 -69
  83. package/src/components/form/inputs/RichText/utils/debug.ts +1 -1
  84. package/src/components/form/inputs/RichText/utils/formatting.ts +39 -39
  85. package/src/components/form/inputs/RichText/utils/media.ts +6 -6
  86. package/src/components/form/inputs/RichText/utils/selection.ts +28 -28
  87. package/src/components/form/inputs/RichText/utils/table.ts +19 -19
  88. package/src/components/form/inputs/SelectBtn.vue +1 -1
  89. package/src/components/form/inputs/SelectInput.vue +50 -26
  90. package/src/components/form/inputs/SignaturePad.vue +15 -15
  91. package/src/components/form/inputs/TableField.vue +1 -1
  92. package/src/components/form/inputs/TelInput.vue +6 -6
  93. package/src/components/form/inputs/TextInput.vue +5 -5
  94. package/src/components/form/inputs/ToggleInput.vue +2 -1
  95. package/src/components/form/inputs/Upload/UploadInput.vue +155 -102
  96. package/src/components/form/inputs/Upload/upload.ts +1 -1
  97. package/src/components/form/inputs/Upload/useFileUpload.ts +6 -6
  98. package/src/components/form/useBagelFormState.ts +5 -5
  99. package/src/components/layout/AppContent.vue +1 -1
  100. package/src/components/layout/AppLayout.vue +1 -1
  101. package/src/components/layout/Layout.vue +4 -4
  102. package/src/components/layout/TabbedLayout.vue +1 -1
  103. package/src/components/layout/Tabs.vue +2 -2
  104. package/src/components/layout/TabsNav.vue +7 -7
  105. package/src/components/lightbox/Lightbox.vue +8 -8
  106. package/src/components/lightbox/index.ts +8 -8
  107. package/src/composables/index.ts +2 -2
  108. package/src/composables/useAddToCalendar.ts +13 -13
  109. package/src/composables/useDevice.ts +2 -2
  110. package/src/composables/useExcel.ts +6 -6
  111. package/src/composables/useFormField.ts +5 -9
  112. package/src/composables/usePolling.ts +8 -8
  113. package/src/composables/useSchemaField.ts +53 -38
  114. package/src/composables/useTheme.ts +9 -9
  115. package/src/composables/useValidateFieldValue.ts +2 -2
  116. package/src/directives/pattern.ts +25 -25
  117. package/src/directives/ripple.ts +4 -4
  118. package/src/directives/vResize.ts +6 -6
  119. package/src/plugins/bagel.ts +4 -4
  120. package/src/plugins/useModal.ts +3 -3
  121. package/src/styles/layout.css +7 -1
  122. package/src/utils/BagelFormUtils.ts +7 -7
  123. package/src/utils/calendar/Helpers.ts +8 -8
  124. package/src/utils/calendar/dateUtils.ts +22 -22
  125. package/src/utils/calendar/time.ts +25 -25
  126. package/src/utils/calendar/week.ts +25 -25
  127. package/src/utils/elementUtils.ts +27 -27
  128. package/src/utils/index.ts +22 -22
  129. package/src/utils/sizeParsing.ts +2 -2
  130. package/src/utils/strings.ts +5 -5
  131. package/src/utils/tapDetector.ts +11 -11
  132. package/src/utils/useSearch.ts +29 -29
  133. package/vite.config.ts +1 -1
@@ -3,39 +3,39 @@ import { analyzeSelection, restoreSelection, getBlocksBetween } from './selectio
3
3
 
4
4
  export function formatting(state: EditorState) {
5
5
  const { doc } = state
6
- if (!doc) return { text: () => {}, block: () => {}, list: () => {}, clear: () => {} }
6
+ if (!doc) {return { text: () => {}, block: () => {}, list: () => {}, clear: () => {} }}
7
7
 
8
8
  const text = (command: string) => {
9
9
  const selection = doc.getSelection()
10
- if (!selection || !selection.rangeCount) return
10
+ if (!selection || !selection.rangeCount) {return}
11
11
 
12
12
  const range = selection.getRangeAt(0)
13
13
  const container = range.commonAncestorContainer
14
- const parentBlock = container.nodeType === 3 ? container.parentElement : container as HTMLElement
14
+ const parentBlock = 3 === container.nodeType ? container.parentElement : container as HTMLElement
15
15
 
16
16
  // Preserve RTL direction when applying text formatting
17
- const isRTL = parentBlock?.closest('[dir="rtl"]') !== null
17
+ const isRTL = null !== parentBlock?.closest('[dir="rtl"]')
18
18
 
19
19
  // Don't apply inline styles directly to block elements
20
20
  if (parentBlock?.tagName.match(/^H[1-6]|P|BLOCKQUOTE|LI$/)) {
21
21
  if (!range.collapsed && range.toString().trim()) {
22
22
  let element: HTMLElement
23
- if (command === 'underline') element = doc.createElement('u')
24
- else if (command === 'bold') element = doc.createElement('b')
25
- else if (command === 'italic') element = doc.createElement('i')
26
- else return
23
+ if ('underline' === command) {element = doc.createElement('u')}
24
+ else if ('bold' === command) {element = doc.createElement('b')}
25
+ else if ('italic' === command) {element = doc.createElement('i')}
26
+ else {return}
27
27
 
28
- if (isRTL) element.dir = 'rtl'
28
+ if (isRTL) {element.dir = 'rtl'}
29
29
  range.surroundContents(element)
30
30
  }
31
31
  } else {
32
- if (range.collapsed) return // No selection, nothing to format
32
+ if (range.collapsed) {return} // No selection, nothing to format
33
33
 
34
34
  let element: HTMLElement
35
- if (command === 'bold') element = doc.createElement('b')
36
- else if (command === 'italic') element = doc.createElement('i')
37
- else if (command === 'underline') element = doc.createElement('u')
38
- else return
35
+ if ('bold' === command) {element = doc.createElement('b')}
36
+ else if ('italic' === command) {element = doc.createElement('i')}
37
+ else if ('underline' === command) {element = doc.createElement('u')}
38
+ else {return}
39
39
 
40
40
  try {
41
41
  range.surroundContents(element)
@@ -51,12 +51,12 @@ export function formatting(state: EditorState) {
51
51
 
52
52
  const block = (command: string, tag: string) => {
53
53
  const selection = doc.getSelection()
54
- if (!selection || !selection.rangeCount) return
54
+ if (!selection || !selection.rangeCount) {return}
55
55
 
56
56
  const range = selection.getRangeAt(0)
57
57
  const container = range.commonAncestorContainer
58
- const parentBlock = container.nodeType === 3 ? container.parentElement : container as HTMLElement
59
- const isRTL = parentBlock?.closest('[dir="rtl"]') !== null
58
+ const parentBlock = 3 === container.nodeType ? container.parentElement : container as HTMLElement
59
+ const isRTL = null !== parentBlock?.closest('[dir="rtl"]')
60
60
 
61
61
  // Remove any invalid inline style wrapping
62
62
  if (parentBlock?.closest('u, b, i')) {
@@ -72,7 +72,7 @@ export function formatting(state: EditorState) {
72
72
 
73
73
  // Create a new block element of the desired type
74
74
  const newBlock = doc.createElement(tag)
75
- if (isRTL) newBlock.dir = 'rtl'
75
+ if (isRTL) {newBlock.dir = 'rtl'}
76
76
 
77
77
  // Find the current block to replace
78
78
  const currentBlock = parentBlock?.closest('p,h1,h2,h3,h4,h5,h6,blockquote,div') || parentBlock
@@ -95,25 +95,25 @@ export function formatting(state: EditorState) {
95
95
  }
96
96
 
97
97
  const list = (command: string) => {
98
- if (!state.doc || !state.range || !state.selection) return
98
+ if (!state.doc || !state.range || !state.selection) {return}
99
99
 
100
- const listTag = command === 'orderedList' ? 'ol' : 'ul'
100
+ const listTag = 'orderedList' === command ? 'ol' : 'ul'
101
101
  const selectionInfo = analyzeSelection(state.doc, state.range)
102
- if (!selectionInfo) return
102
+ if (!selectionInfo) {return}
103
103
 
104
- const isRTL = selectionInfo.parent.closest('[dir="rtl"]') !== null
104
+ const isRTL = null !== selectionInfo.parent.closest('[dir="rtl"]')
105
105
 
106
106
  // If we're inside a list item, handle toggling off or switching list type
107
107
  const listItem = selectionInfo.parent.closest('li')
108
108
  if (listItem) {
109
109
  const listParent = listItem.parentElement
110
- if (!listParent) return
110
+ if (!listParent) {return}
111
111
 
112
112
  // If it's the same list type, toggle off
113
113
  if (listParent.tagName.toLowerCase() === listTag) {
114
114
  // Create a paragraph from the list item content
115
115
  const p = state.doc.createElement('p') as HTMLParagraphElement
116
- if (isRTL) p.dir = 'rtl'
116
+ if (isRTL) {p.dir = 'rtl'}
117
117
  while (listItem.firstChild) {
118
118
  p.appendChild(listItem.firstChild)
119
119
  }
@@ -131,7 +131,7 @@ export function formatting(state: EditorState) {
131
131
 
132
132
  // Convert to the other list type
133
133
  const newList = state.doc.createElement(listTag) as HTMLElement
134
- if (isRTL) newList.dir = 'rtl'
134
+ if (isRTL) {newList.dir = 'rtl'}
135
135
  const allItems = Array.from(listParent.children)
136
136
  allItems.forEach(item => newList.appendChild(item.cloneNode(true)))
137
137
  listParent.parentNode?.replaceChild(newList, listParent)
@@ -145,7 +145,7 @@ export function formatting(state: EditorState) {
145
145
  if (!selectionInfo.isMultiBlock) {
146
146
  const li = state.doc.createElement('li')
147
147
  const listEl = state.doc.createElement(listTag) as HTMLElement
148
- if (isRTL) listEl.dir = 'rtl'
148
+ if (isRTL) {listEl.dir = 'rtl'}
149
149
 
150
150
  while (selectionInfo.startBlock.firstChild) {
151
151
  li.appendChild(selectionInfo.startBlock.firstChild)
@@ -160,10 +160,10 @@ export function formatting(state: EditorState) {
160
160
  // Handle multi-block selection
161
161
  const blocks = getBlocksBetween(selectionInfo.startBlock, selectionInfo.endBlock)
162
162
  const listEl = state.doc.createElement(listTag) as HTMLElement
163
- if (isRTL) listEl.dir = 'rtl'
163
+ if (isRTL) {listEl.dir = 'rtl'}
164
164
 
165
165
  blocks.forEach((block) => {
166
- if (!state.doc) return
166
+ if (!state.doc) {return}
167
167
  const li = state.doc.createElement('li')
168
168
  while (block.firstChild) {
169
169
  li.appendChild(block.firstChild)
@@ -216,14 +216,14 @@ export function formatting(state: EditorState) {
216
216
 
217
217
  // Function to recursively clean a node and its children
218
218
  const cleanNode = (node: Node): Node => {
219
- if (!state.doc) return node
219
+ if (!state.doc) {return node}
220
220
 
221
221
  // Text nodes can be returned as-is
222
- if (node.nodeType === 3) {
222
+ if (3 === node.nodeType) {
223
223
  return node.cloneNode(true)
224
224
  }
225
225
 
226
- if (node.nodeType === 1) { // Element node
226
+ if (1 === node.nodeType) { // Element node
227
227
  const el = node as HTMLElement
228
228
  const nodeName = el.nodeName.toLowerCase()
229
229
  const inlineTags = ['b', 'i', 'u', 'strong', 'em', 'span', 'font', 'strike', 'sub', 'sup']
@@ -254,7 +254,7 @@ export function formatting(state: EditorState) {
254
254
  }
255
255
 
256
256
  // Transfer only specific attributes we want to keep (like href for links)
257
- if (nodeName === 'a' && el.hasAttribute('href')) {
257
+ if ('a' === nodeName && el.hasAttribute('href')) {
258
258
  newEl.setAttribute('href', el.getAttribute('href') || '')
259
259
  if (el.hasAttribute('target')) {
260
260
  newEl.setAttribute('target', el.getAttribute('target') || '')
@@ -263,9 +263,9 @@ export function formatting(state: EditorState) {
263
263
  }
264
264
 
265
265
  // For images, preserve src and alt
266
- if (nodeName === 'img') {
267
- if (el.hasAttribute('src')) newEl.setAttribute('src', el.getAttribute('src') || '')
268
- if (el.hasAttribute('alt')) newEl.setAttribute('alt', el.getAttribute('alt') || '')
266
+ if ('img' === nodeName) {
267
+ if (el.hasAttribute('src')) {newEl.setAttribute('src', el.getAttribute('src') || '')}
268
+ if (el.hasAttribute('alt')) {newEl.setAttribute('alt', el.getAttribute('alt') || '')}
269
269
  console.log('[Clear Format] Preserving image attributes')
270
270
  }
271
271
 
@@ -307,17 +307,17 @@ export function formatting(state: EditorState) {
307
307
  }
308
308
 
309
309
  export function getBlockElement(node: Node): HTMLElement | null {
310
- const element = node.nodeType === 3 ? node.parentElement : node as HTMLElement
311
- if (!element) return null
310
+ const element = 3 === node.nodeType ? node.parentElement : node as HTMLElement
311
+ if (!element) {return null}
312
312
  return element.closest('p,h1,h2,h3,h4,h5,h6,blockquote,li') || element
313
313
  }
314
314
 
315
315
  export function adjustIndentation(state: EditorState, increase: boolean) {
316
316
  const { doc, range } = state
317
- if (!doc || !range) return
317
+ if (!doc || !range) {return}
318
318
 
319
319
  const blockElement = getBlockElement(range.commonAncestorContainer)
320
- if (!blockElement) return
320
+ if (!blockElement) {return}
321
321
 
322
322
  const currentMargin = Number.parseInt(blockElement.style.marginLeft || '0', 10)
323
323
  const step = 20 // pixels to indent/outdent
@@ -4,7 +4,7 @@ import { bagelFormUtils as frm } from '../../../../../utils'
4
4
 
5
5
  export function insertImage(modal: ModalApi, state: EditorState) {
6
6
  const { range, doc } = state
7
- if (!range || !doc) return
7
+ if (!range || !doc) {return}
8
8
 
9
9
  modal.showModalForm<{
10
10
  src: string
@@ -107,7 +107,7 @@ export function insertLink(modal: ModalApi, state: EditorState) {
107
107
 
108
108
  // Helper function to select word at cursor
109
109
  function selectWordAtCursor(doc: Document, range: Range): boolean {
110
- if (!range.collapsed) return true // Already has selection
110
+ if (!range.collapsed) {return true} // Already has selection
111
111
 
112
112
  let textNode = range.startContainer
113
113
  let offset = range.startOffset
@@ -115,7 +115,7 @@ function selectWordAtCursor(doc: Document, range: Range): boolean {
115
115
  // If we're in an element node, try to find a text node
116
116
  if (textNode.nodeType !== Node.TEXT_NODE) {
117
117
  const element = textNode as Element
118
- if (element.childNodes.length > 0 && offset < element.childNodes.length) {
118
+ if (0 < element.childNodes.length && offset < element.childNodes.length) {
119
119
  const childNode = element.childNodes[offset]
120
120
  if (childNode.nodeType === Node.TEXT_NODE) {
121
121
  textNode = childNode
@@ -129,7 +129,7 @@ function selectWordAtCursor(doc: Document, range: Range): boolean {
129
129
  }
130
130
 
131
131
  const text = textNode.textContent || ''
132
- if (!text) return false
132
+ if (!text) {return false}
133
133
 
134
134
  // Find word boundaries - support Hebrew, English, and numbers
135
135
  let start = offset
@@ -139,7 +139,7 @@ function selectWordAtCursor(doc: Document, range: Range): boolean {
139
139
  const wordRegex = /[\u0590-\u05FF\u0600-\u06FF\w]/
140
140
 
141
141
  // Move start backwards to find beginning of word
142
- while (start > 0 && wordRegex.test(text[start - 1])) {
142
+ while (0 < start && wordRegex.test(text[start - 1])) {
143
143
  start--
144
144
  }
145
145
 
@@ -173,7 +173,7 @@ export interface InsertImbedModalData {
173
173
 
174
174
  export function insertEmbed(modal: ModalApi, state: EditorState) {
175
175
  const { range, doc } = state
176
- if (!range || !doc) return
176
+ if (!range || !doc) {return}
177
177
 
178
178
  modal.showModalForm<InsertImbedModalData>({
179
179
  title: 'Embed iframe',
@@ -8,18 +8,18 @@ export function getSelectionRange(state: any) {
8
8
 
9
9
  export function isStyleActive(style: string, doc: Document) {
10
10
  const selection = doc.getSelection()
11
- if (!selection || !selection.rangeCount) return false
11
+ if (!selection || !selection.rangeCount) {return false}
12
12
 
13
13
  const range = selection.getRangeAt(0)
14
14
  const container = range.commonAncestorContainer
15
15
  const parent = container.nodeType === Node.TEXT_NODE ? container.parentElement : container as Element
16
16
 
17
- if (!parent) return false
17
+ if (!parent) {return false}
18
18
 
19
19
  // Check if the current node or any parent has the style
20
20
  const checkParent = (element: Element | null, checker: (el: Element) => boolean): boolean => {
21
- if (!element) return false
22
- if (checker(element)) return true
21
+ if (!element) {return false}
22
+ if (checker(element)) {return true}
23
23
  return checkParent(element.parentElement, checker)
24
24
  }
25
25
 
@@ -29,30 +29,30 @@ export function isStyleActive(style: string, doc: Document) {
29
29
  bold: (el) => {
30
30
  const tagName = el.tagName?.toLowerCase()
31
31
  // Only consider <b> and <strong> tags, not CSS bold styling
32
- return tagName === 'strong' || tagName === 'b'
32
+ return 'strong' === tagName || 'b' === tagName
33
33
  },
34
34
 
35
35
  italic: (el) => {
36
36
  const tagName = el.tagName?.toLowerCase()
37
37
  // Only consider <i> and <em> tags, not CSS italic styling
38
- return tagName === 'em' || tagName === 'i'
38
+ return 'em' === tagName || 'i' === tagName
39
39
  },
40
40
 
41
41
  underline: (el) => {
42
42
  const tagName = el.tagName?.toLowerCase()
43
43
  // Only consider <u> tag, not CSS underline styling
44
- return tagName === 'u'
44
+ return 'u' === tagName
45
45
  },
46
46
 
47
47
  // Block elements
48
- h1: el => el.tagName?.toLowerCase() === 'h1',
49
- h2: el => el.tagName?.toLowerCase() === 'h2',
50
- h3: el => el.tagName?.toLowerCase() === 'h3',
51
- h4: el => el.tagName?.toLowerCase() === 'h4',
52
- h5: el => el.tagName?.toLowerCase() === 'h5',
53
- h6: el => el.tagName?.toLowerCase() === 'h6',
54
- p: el => el.tagName?.toLowerCase() === 'p',
55
- blockquote: el => el.tagName?.toLowerCase() === 'blockquote',
48
+ h1: el => 'h1' === el.tagName?.toLowerCase(),
49
+ h2: el => 'h2' === el.tagName?.toLowerCase(),
50
+ h3: el => 'h3' === el.tagName?.toLowerCase(),
51
+ h4: el => 'h4' === el.tagName?.toLowerCase(),
52
+ h5: el => 'h5' === el.tagName?.toLowerCase(),
53
+ h6: el => 'h6' === el.tagName?.toLowerCase(),
54
+ p: el => 'p' === el.tagName?.toLowerCase(),
55
+ blockquote: el => 'blockquote' === el.tagName?.toLowerCase(),
56
56
 
57
57
  // List elements - check if we're inside a list
58
58
  orderedList: (el) => {
@@ -68,33 +68,33 @@ export function isStyleActive(style: string, doc: Document) {
68
68
  // Text alignment
69
69
  alignLeft: (el) => {
70
70
  const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
71
- return (paragraph as HTMLElement)?.style.textAlign === 'start'
71
+ return 'start' === (paragraph as HTMLElement)?.style.textAlign
72
72
  },
73
73
  alignCenter: (el) => {
74
74
  const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
75
- return (paragraph as HTMLElement)?.style.textAlign === 'center'
75
+ return 'center' === (paragraph as HTMLElement)?.style.textAlign
76
76
  },
77
77
  alignRight: (el) => {
78
78
  const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
79
- return (paragraph as HTMLElement)?.style.textAlign === 'end'
79
+ return 'end' === (paragraph as HTMLElement)?.style.textAlign
80
80
  },
81
81
  alignJustify: (el) => {
82
82
  const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
83
- return (paragraph as HTMLElement)?.style.textAlign === 'justify'
83
+ return 'justify' === (paragraph as HTMLElement)?.style.textAlign
84
84
  },
85
85
 
86
86
  // Text direction
87
87
  textDirection: (el) => {
88
88
  const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
89
- return (paragraph as HTMLElement)?.dir === 'rtl'
89
+ return 'rtl' === (paragraph as HTMLElement)?.dir
90
90
  },
91
91
  ltrDirection: (el) => {
92
92
  const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
93
- return (paragraph as HTMLElement)?.dir === 'ltr'
93
+ return 'ltr' === (paragraph as HTMLElement)?.dir
94
94
  },
95
95
  rtlDirection: (el) => {
96
96
  const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
97
- return (paragraph as HTMLElement)?.dir === 'rtl'
97
+ return 'rtl' === (paragraph as HTMLElement)?.dir
98
98
  }
99
99
  }
100
100
 
@@ -126,8 +126,8 @@ export interface SelectionInfo {
126
126
 
127
127
  export function analyzeSelection(doc: Document, range: Range): SelectionInfo | null {
128
128
  const container = range.commonAncestorContainer
129
- const parent = container.nodeType === 3 ? container.parentElement : container as Element
130
- if (!parent) return null
129
+ const parent = 3 === container.nodeType ? container.parentElement : container as Element
130
+ if (!parent) {return null}
131
131
 
132
132
  const startBlock = parent.closest('p,h1,h2,h3,h4,h5,h6,blockquote,li') || parent
133
133
 
@@ -135,7 +135,7 @@ export function analyzeSelection(doc: Document, range: Range): SelectionInfo | n
135
135
  const isMultiBlock = (() => {
136
136
  if (!range.collapsed) {
137
137
  const { endContainer } = range
138
- const endParent = endContainer.nodeType === 3 ? endContainer.parentElement : endContainer as Element
138
+ const endParent = 3 === endContainer.nodeType ? endContainer.parentElement : endContainer as Element
139
139
  const endBlock = endParent?.closest('p,h1,h2,h3,h4,h5,h6,blockquote,li') || endParent
140
140
  return startBlock !== endBlock
141
141
  }
@@ -143,10 +143,10 @@ export function analyzeSelection(doc: Document, range: Range): SelectionInfo | n
143
143
  })()
144
144
 
145
145
  const { endContainer } = range
146
- const endParent = endContainer.nodeType === 3 ? endContainer.parentElement : endContainer as Element
146
+ const endParent = 3 === endContainer.nodeType ? endContainer.parentElement : endContainer as Element
147
147
  const endBlock = endParent?.closest('p,h1,h2,h3,h4,h5,h6,blockquote,li') || endParent
148
148
 
149
- if (!endBlock) return null
149
+ if (!endBlock) {return null}
150
150
 
151
151
  return {
152
152
  startBlock,
@@ -184,7 +184,7 @@ export function getBlocksBetween(startBlock: Element, endBlock: Element): Elemen
184
184
  let currentBlock = startBlock
185
185
  while (currentBlock) {
186
186
  blocks.push(currentBlock)
187
- if (currentBlock === endBlock) break
187
+ if (currentBlock === endBlock) {break}
188
188
  currentBlock = currentBlock.nextElementSibling as Element
189
189
  }
190
190
  return blocks
@@ -1,7 +1,7 @@
1
1
  import type { EditorState } from '../richTextTypes'
2
2
 
3
3
  export function insertTable(rows: number, cols: number, state: EditorState) {
4
- if (!state.doc) return
4
+ if (!state.doc) {return}
5
5
  const table = state.doc.createElement('table')
6
6
  table.style.width = '100%'
7
7
  table.style.borderCollapse = 'collapse'
@@ -59,10 +59,10 @@ export function insertTable(rows: number, cols: number, state: EditorState) {
59
59
 
60
60
  export function mergeCells(range: Range, doc: Document) {
61
61
  const cells = Array.from(range.cloneContents().querySelectorAll('td'))
62
- if (cells.length < 2) return
62
+ if (2 > cells.length) {return}
63
63
 
64
64
  const firstCell = range.startContainer.parentElement?.closest('td')
65
- if (!firstCell) return
65
+ if (!firstCell) {return}
66
66
 
67
67
  firstCell.colSpan = cells.length
68
68
  firstCell.innerHTML = cells.map(cell => cell.innerHTML).join(' ')
@@ -81,7 +81,7 @@ export function mergeCells(range: Range, doc: Document) {
81
81
 
82
82
  export function splitCell(range: Range, doc: Document) {
83
83
  const cell = range.startContainer.parentElement?.closest('td')
84
- if (!cell || !cell.colSpan || cell.colSpan === 1) return
84
+ if (!cell || !cell.colSpan || 1 === cell.colSpan) {return}
85
85
 
86
86
  const newCells = new Array(cell.colSpan - 1).fill(0).map(() => {
87
87
  const newCell = doc.createElement('td')
@@ -106,16 +106,16 @@ export function splitCell(range: Range, doc: Document) {
106
106
 
107
107
  export function addRow(position: 'before' | 'after', range: Range, doc: Document) {
108
108
  const cell = range.startContainer.parentElement?.closest('td')
109
- if (!cell) return
109
+ if (!cell) {return}
110
110
 
111
111
  const row = cell.parentElement
112
112
  const table = row?.parentElement
113
- if (!row || !table) return
113
+ if (!row || !table) {return}
114
114
 
115
115
  const newRow = row.cloneNode(true) as HTMLTableRowElement
116
116
  Array.from(newRow.cells).forEach(cell => cell.innerHTML = '&nbsp;')
117
117
 
118
- row.insertAdjacentElement(position === 'before' ? 'beforebegin' : 'afterend', newRow)
118
+ row.insertAdjacentElement('before' === position ? 'beforebegin' : 'afterend', newRow)
119
119
 
120
120
  // Update state content
121
121
  const state = (doc as any).editorState as EditorState
@@ -126,10 +126,10 @@ export function addRow(position: 'before' | 'after', range: Range, doc: Document
126
126
 
127
127
  export function deleteRow(range: Range) {
128
128
  const cell = range.startContainer.parentElement?.closest('td')
129
- if (!cell) return
129
+ if (!cell) {return}
130
130
 
131
131
  const row = cell.parentElement
132
- if (!row) return
132
+ if (!row) {return}
133
133
 
134
134
  const doc = row.ownerDocument
135
135
  row.remove()
@@ -143,10 +143,10 @@ export function deleteRow(range: Range) {
143
143
 
144
144
  export function deleteTable(range: Range) {
145
145
  const cell = range.startContainer.parentElement?.closest('td')
146
- if (!cell) return
146
+ if (!cell) {return}
147
147
 
148
148
  const table = cell.closest('table')
149
- if (!table) return
149
+ if (!table) {return}
150
150
 
151
151
  const doc = table.ownerDocument
152
152
  table.remove()
@@ -160,16 +160,16 @@ export function deleteTable(range: Range) {
160
160
 
161
161
  export function insertColumn(position: 'before' | 'after', range: Range) {
162
162
  const cell = range.startContainer.parentElement?.closest('td')
163
- if (!cell) return
163
+ if (!cell) {return}
164
164
 
165
165
  const table = cell.closest('table')
166
- if (!table) return
166
+ if (!table) {return}
167
167
 
168
168
  const columnIndex = cell.cellIndex
169
169
  const { rows } = table
170
170
 
171
171
  for (let i = 0; i < rows.length; i++) {
172
- const newCell = rows[i].insertCell(position === 'after' ? columnIndex + 1 : columnIndex)
172
+ const newCell = rows[i].insertCell('after' === position ? columnIndex + 1 : columnIndex)
173
173
  newCell.innerHTML = '&nbsp;'
174
174
  newCell.style.border = '1px solid var(--border-color)'
175
175
  newCell.style.padding = '8px'
@@ -184,10 +184,10 @@ export function insertColumn(position: 'before' | 'after', range: Range) {
184
184
 
185
185
  export function deleteColumn(range: Range) {
186
186
  const cell = range.startContainer.parentElement?.closest('td')
187
- if (!cell) return
187
+ if (!cell) {return}
188
188
 
189
189
  const table = cell.closest('table')
190
- if (!table) return
190
+ if (!table) {return}
191
191
 
192
192
  const columnIndex = cell.cellIndex
193
193
  const { rows } = table
@@ -198,7 +198,7 @@ export function deleteColumn(range: Range) {
198
198
  }
199
199
 
200
200
  // If no columns left, remove the table
201
- if (rows[0].cells.length === 0) {
201
+ if (0 === rows[0].cells.length) {
202
202
  table.remove()
203
203
  }
204
204
 
@@ -211,10 +211,10 @@ export function deleteColumn(range: Range) {
211
211
 
212
212
  export function alignColumn(range: Range, alignment: 'start' | 'center' | 'end' | 'justify') {
213
213
  const cell = range.startContainer.parentElement?.closest('td')
214
- if (!cell) return
214
+ if (!cell) {return}
215
215
 
216
216
  const table = cell.closest('table')
217
- if (!table) return
217
+ if (!table) {return}
218
218
 
219
219
  const columnIndex = cell.cellIndex
220
220
  const { rows } = table
@@ -24,7 +24,7 @@ function toggleOption(value: string | number) {
24
24
  // Multiselect mode - work with arrays
25
25
  const currentValue = Array.isArray(selected.value) ? selected.value : []
26
26
  const index = currentValue.indexOf(value)
27
- if (index > -1) {
27
+ if (-1 < index) {
28
28
  selected.value = currentValue.filter(v => v !== value)
29
29
  } else {
30
30
  selected.value = [...currentValue, value]