@bagelink/vue 1.6.47 → 1.6.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/experimentalGenTypedRoutes.ts +18 -19
- package/bin/utils.ts +4 -4
- package/dist/components/AddressSearch.vue.d.ts.map +1 -1
- package/dist/components/Alert.vue.d.ts.map +1 -1
- package/dist/components/BglVideo.vue.d.ts.map +1 -1
- package/dist/components/Card.vue.d.ts.map +1 -1
- package/dist/components/Carousel.vue.d.ts +2 -2
- package/dist/components/Carousel.vue.d.ts.map +1 -1
- package/dist/components/Dropdown.vue.d.ts.map +1 -1
- package/dist/components/Flag.vue.d.ts.map +1 -1
- package/dist/components/IframeVue.vue.d.ts.map +1 -1
- package/dist/components/ListItem.vue.d.ts.map +1 -1
- package/dist/components/Loading.vue.d.ts.map +1 -1
- package/dist/components/Modal.vue.d.ts.map +1 -1
- package/dist/components/ModalForm.vue.d.ts.map +1 -1
- package/dist/components/NavBar.vue.d.ts +1 -1
- package/dist/components/Pill.vue.d.ts.map +1 -1
- package/dist/components/Zoomer.vue.d.ts +0 -1
- package/dist/components/Zoomer.vue.d.ts.map +1 -1
- package/dist/components/analytics/LineChart.vue.d.ts.map +1 -1
- package/dist/components/analytics/PieChart.vue.d.ts +2 -1
- package/dist/components/analytics/PieChart.vue.d.ts.map +1 -1
- package/dist/components/analytics/index.d.ts +1 -1
- package/dist/components/analytics/index.d.ts.map +1 -1
- package/dist/components/calendar/CalendarPopover.vue.d.ts.map +1 -1
- package/dist/components/form/BglMultiStepForm.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/ColorInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/DateInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/PasswordInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RadioGroup.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RangeInput.vue.d.ts +11 -11
- package/dist/components/form/inputs/RichText/components/EditorToolbar.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/components/TableGridSelector.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/RichText/utils/commands.d.ts.map +1 -1
- package/dist/components/form/inputs/SelectInput.vue.d.ts.map +1 -1
- package/dist/components/form/inputs/TelInput.vue.d.ts.map +1 -1
- package/dist/components/layout/AppSidebar.vue.d.ts +1 -0
- package/dist/components/layout/AppSidebar.vue.d.ts.map +1 -1
- package/dist/components/layout/Layout.vue.d.ts.map +1 -1
- package/dist/components/layout/Tabs.vue.d.ts.map +1 -1
- package/dist/components/layout/index.d.ts +3 -3
- package/dist/components/layout/index.d.ts.map +1 -1
- package/dist/index.cjs +34 -25
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +6668 -5883
- package/dist/plugins/useToast.d.ts.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +5 -10
- package/src/components/AccordionItem.vue +11 -11
- package/src/components/AddToCalendar.vue +1 -1
- package/src/components/AddressSearch.vue +9 -8
- package/src/components/Alert.vue +2 -1
- package/src/components/Badge.vue +5 -5
- package/src/components/BglVideo.vue +44 -45
- package/src/components/Btn.vue +15 -15
- package/src/components/Card.vue +10 -8
- package/src/components/Carousel.vue +159 -162
- package/src/components/DataPreview.vue +1 -1
- package/src/components/DragOver.vue +6 -6
- package/src/components/Dropdown.vue +39 -38
- package/src/components/Flag.vue +7 -6
- package/src/components/Icon/Icon.vue +22 -22
- package/src/components/IframeVue.vue +5 -5
- package/src/components/Image.vue +17 -17
- package/src/components/ImportData.vue +79 -79
- package/src/components/ListItem.vue +20 -13
- package/src/components/Loading.vue +10 -9
- package/src/components/MapEmbed/Index.vue +24 -24
- package/src/components/Modal.vue +11 -9
- package/src/components/ModalForm.vue +9 -8
- package/src/components/NavBar.vue +6 -6
- package/src/components/Pagination.vue +27 -27
- package/src/components/Pill.vue +11 -12
- package/src/components/Rating.vue +2 -2
- package/src/components/Slider.vue +75 -75
- package/src/components/Spreadsheet/Index.vue +34 -34
- package/src/components/Spreadsheet/SpreadsheetTable.vue +3 -3
- package/src/components/Zoomer.vue +165 -170
- package/src/components/analytics/BarChart.vue +6 -6
- package/src/components/analytics/KpiCard.vue +2 -2
- package/src/components/analytics/LineChart.vue +63 -61
- package/src/components/analytics/PieChart.vue +104 -90
- package/src/components/analytics/index.ts +2 -2
- package/src/components/calendar/CalendarPopover.vue +1 -1
- package/src/components/calendar/Index.vue +1 -1
- package/src/components/calendar/views/AgendaView.vue +3 -3
- package/src/components/calendar/views/DayView.vue +6 -6
- package/src/components/calendar/views/MonthView.vue +2 -2
- package/src/components/calendar/views/WeekView.vue +18 -18
- package/src/components/dataTable/DataTable.vue +4 -4
- package/src/components/dataTable/useSorting.ts +1 -1
- package/src/components/dataTable/useTableData.ts +15 -15
- package/src/components/dataTable/useTableSelection.ts +15 -15
- package/src/components/dataTable/useTableVirtualization.ts +1 -1
- package/src/components/draggable/useDraggable.ts +42 -42
- package/src/components/form/BagelForm.vue +15 -15
- package/src/components/form/BglFieldSet.vue +5 -3
- package/src/components/form/BglMultiStepForm.vue +20 -21
- package/src/components/form/inputs/CheckInput.vue +2 -2
- package/src/components/form/inputs/CodeEditor/format.ts +7 -7
- package/src/components/form/inputs/CodeEditor/useHighlight.ts +6 -6
- package/src/components/form/inputs/ColorInput.vue +5 -4
- package/src/components/form/inputs/DateInput.vue +8 -9
- package/src/components/form/inputs/DatePicker.vue +24 -24
- package/src/components/form/inputs/EmailInput.vue +24 -24
- package/src/components/form/inputs/NumberInput.vue +26 -26
- package/src/components/form/inputs/OTP.vue +7 -7
- package/src/components/form/inputs/PasswordInput.vue +3 -2
- package/src/components/form/inputs/RadioGroup.vue +28 -25
- package/src/components/form/inputs/RadioPillsInput.vue +12 -12
- package/src/components/form/inputs/RangeInput.vue +21 -21
- package/src/components/form/inputs/RichText/components/EditorToolbar.vue +107 -92
- package/src/components/form/inputs/RichText/components/TableGridSelector.vue +64 -64
- package/src/components/form/inputs/RichText/components/gridBox.vue +10 -8
- package/src/components/form/inputs/RichText/composables/useCommands.ts +1 -1
- package/src/components/form/inputs/RichText/composables/useEditor.ts +12 -12
- package/src/components/form/inputs/RichText/composables/useEditorKeyboard.ts +1 -1
- package/src/components/form/inputs/RichText/index.vue +138 -138
- package/src/components/form/inputs/RichText/utils/commands.ts +84 -85
- package/src/components/form/inputs/RichText/utils/debug.ts +1 -1
- package/src/components/form/inputs/RichText/utils/formatting.ts +39 -39
- package/src/components/form/inputs/RichText/utils/selection.ts +28 -28
- package/src/components/form/inputs/RichText/utils/table.ts +19 -19
- package/src/components/form/inputs/SelectBtn.vue +1 -1
- package/src/components/form/inputs/SelectInput.vue +54 -54
- package/src/components/form/inputs/SignaturePad.vue +40 -40
- package/src/components/form/inputs/TableField.vue +1 -1
- package/src/components/form/inputs/TelInput.vue +54 -53
- package/src/components/form/inputs/TextInput.vue +19 -19
- package/src/components/form/inputs/ToggleInput.vue +2 -2
- package/src/components/form/inputs/Upload/useFileUpload.ts +6 -6
- package/src/components/form/useBagelFormState.ts +5 -5
- package/src/components/layout/AppLayout.vue +2 -2
- package/src/components/layout/AppSidebar.vue +77 -16
- package/src/components/layout/Layout.vue +12 -10
- package/src/components/layout/SidebarMenu.vue +4 -4
- package/src/components/layout/TabbedLayout.vue +17 -17
- package/src/components/layout/Tabs.vue +4 -5
- package/src/components/layout/TabsNav.vue +14 -14
- package/src/components/layout/index.ts +3 -5
- package/src/components/lightbox/Lightbox.vue +22 -22
- package/src/components/lightbox/index.ts +8 -8
- package/src/composables/index.ts +8 -8
- package/src/composables/useAddToCalendar.ts +13 -13
- package/src/composables/useDevice.ts +2 -2
- package/src/composables/useFormField.ts +4 -4
- package/src/composables/usePolling.ts +8 -8
- package/src/composables/useSchemaField.ts +38 -38
- package/src/composables/useTheme.ts +9 -9
- package/src/composables/useValidateFieldValue.ts +2 -2
- package/src/directives/pattern.ts +25 -25
- package/src/directives/ripple.ts +4 -4
- package/src/directives/vResize.ts +6 -6
- package/src/index.ts +1 -0
- package/src/plugins/bagel.ts +4 -4
- package/src/plugins/useToast.ts +56 -51
- package/src/styles/layout.css +1 -1
- package/src/types/index.ts +1 -1
- package/src/utils/BagelFormUtils.ts +7 -7
- package/src/utils/calendar/Helpers.ts +8 -8
- package/src/utils/calendar/dateUtils.ts +22 -22
- package/src/utils/calendar/time.ts +25 -25
- package/src/utils/calendar/week.ts +25 -25
- package/src/utils/elementUtils.ts +27 -27
- package/src/utils/sizeParsing.ts +2 -2
- package/src/utils/strings.ts +5 -5
- package/src/utils/tapDetector.ts +11 -11
- package/src/utils/useSearch.ts +29 -29
- package/vite.config.ts +0 -2
|
@@ -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 =
|
|
14
|
+
const parentBlock = container.nodeType === 3 ? container.parentElement : container as HTMLElement
|
|
15
15
|
|
|
16
16
|
// Preserve RTL direction when applying text formatting
|
|
17
|
-
const isRTL =
|
|
17
|
+
const isRTL = parentBlock?.closest('[dir="rtl"]') !== null
|
|
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 ('underline'
|
|
24
|
-
else if ('bold'
|
|
25
|
-
else if ('italic'
|
|
26
|
-
else {return}
|
|
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 }
|
|
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 ('bold'
|
|
36
|
-
else if ('italic'
|
|
37
|
-
else if ('underline'
|
|
38
|
-
else {return}
|
|
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 }
|
|
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 =
|
|
59
|
-
const isRTL =
|
|
58
|
+
const parentBlock = container.nodeType === 3 ? container.parentElement : container as HTMLElement
|
|
59
|
+
const isRTL = parentBlock?.closest('[dir="rtl"]') !== null
|
|
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 = 'orderedList'
|
|
100
|
+
const listTag = command === 'orderedList' ? 'ol' : 'ul'
|
|
101
101
|
const selectionInfo = analyzeSelection(state.doc, state.range)
|
|
102
|
-
if (!selectionInfo) {return}
|
|
102
|
+
if (!selectionInfo) { return }
|
|
103
103
|
|
|
104
|
-
const isRTL =
|
|
104
|
+
const isRTL = selectionInfo.parent.closest('[dir="rtl"]') !== null
|
|
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 (
|
|
222
|
+
if (node.nodeType === 3) {
|
|
223
223
|
return node.cloneNode(true)
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
if (
|
|
226
|
+
if (node.nodeType === 1) { // 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 ('a'
|
|
257
|
+
if (nodeName === 'a' && 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 ('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 (nodeName === 'img') {
|
|
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 =
|
|
311
|
-
if (!element) {return null}
|
|
310
|
+
const element = node.nodeType === 3 ? 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
|
|
@@ -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 'strong'
|
|
32
|
+
return tagName === 'strong' || tagName === 'b'
|
|
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 'em'
|
|
38
|
+
return tagName === 'em' || tagName === 'i'
|
|
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 'u'
|
|
44
|
+
return tagName === 'u'
|
|
45
45
|
},
|
|
46
46
|
|
|
47
47
|
// Block elements
|
|
48
|
-
h1: el =>
|
|
49
|
-
h2: el =>
|
|
50
|
-
h3: el =>
|
|
51
|
-
h4: el =>
|
|
52
|
-
h5: el =>
|
|
53
|
-
h6: el =>
|
|
54
|
-
p: el =>
|
|
55
|
-
blockquote: el =>
|
|
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',
|
|
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
|
|
71
|
+
return (paragraph as HTMLElement)?.style.textAlign === 'start'
|
|
72
72
|
},
|
|
73
73
|
alignCenter: (el) => {
|
|
74
74
|
const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
|
|
75
|
-
return
|
|
75
|
+
return (paragraph as HTMLElement)?.style.textAlign === 'center'
|
|
76
76
|
},
|
|
77
77
|
alignRight: (el) => {
|
|
78
78
|
const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
|
|
79
|
-
return
|
|
79
|
+
return (paragraph as HTMLElement)?.style.textAlign === 'end'
|
|
80
80
|
},
|
|
81
81
|
alignJustify: (el) => {
|
|
82
82
|
const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
|
|
83
|
-
return
|
|
83
|
+
return (paragraph as HTMLElement)?.style.textAlign === 'justify'
|
|
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
|
|
89
|
+
return (paragraph as HTMLElement)?.dir === 'rtl'
|
|
90
90
|
},
|
|
91
91
|
ltrDirection: (el) => {
|
|
92
92
|
const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
|
|
93
|
-
return
|
|
93
|
+
return (paragraph as HTMLElement)?.dir === 'ltr'
|
|
94
94
|
},
|
|
95
95
|
rtlDirection: (el) => {
|
|
96
96
|
const paragraph = el.closest('p, h1, h2, h3, h4, h5, h6')
|
|
97
|
-
return
|
|
97
|
+
return (paragraph as HTMLElement)?.dir === 'rtl'
|
|
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 =
|
|
130
|
-
if (!parent) {return null}
|
|
129
|
+
const parent = container.nodeType === 3 ? 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 =
|
|
138
|
+
const endParent = endContainer.nodeType === 3 ? 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 =
|
|
146
|
+
const endParent = endContainer.nodeType === 3 ? 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 (
|
|
62
|
+
if (cells.length < 2) { 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 ||
|
|
84
|
+
if (!cell || !cell.colSpan || cell.colSpan === 1) { 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 = ' ')
|
|
117
117
|
|
|
118
|
-
row.insertAdjacentElement('before'
|
|
118
|
+
row.insertAdjacentElement(position === 'before' ? '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('after'
|
|
172
|
+
const newCell = rows[i].insertCell(position === 'after' ? columnIndex + 1 : columnIndex)
|
|
173
173
|
newCell.innerHTML = ' '
|
|
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 (
|
|
201
|
+
if (rows[0].cells.length === 0) {
|
|
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 (-1
|
|
27
|
+
if (index > -1) {
|
|
28
28
|
selected.value = currentValue.filter(v => v !== value)
|
|
29
29
|
} else {
|
|
30
30
|
selected.value = [...currentValue, value]
|