@sovann72-dev/lynqify-ui 1.0.0 → 1.0.1
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/dist/components/NoteEditor/BatchImageGalleryNodeView.d.ts +19 -0
- package/dist/components/RichTextEditor/Extension/Indent/backspace.indent.handlers.d.ts +18 -0
- package/dist/components/RichTextEditor/Extension/Indent/indent.extension.d.ts +26 -0
- package/dist/components/RichTextEditor/Extension/Indent/indent.handlers.d.ts +16 -0
- package/{src/components/RichTextEditor/Extension/Indent/indent.types.ts → dist/components/RichTextEditor/Extension/Indent/indent.types.d.ts} +10 -35
- package/dist/components/RichTextEditor/Extension/Indent/indent.utils.d.ts +8 -0
- package/dist/components/RichTextEditor/Extension/Indent/outdent.handlers.d.ts +6 -0
- package/dist/components/RichTextEditor/Extension/Indent/shifttab.indent.handlers.d.ts +18 -0
- package/dist/components/RichTextEditor/Extension/Indent/tab.indent.handlers.d.ts +21 -0
- package/dist/components/RichTextEditor/Extension/List/custom-list-item.extension.d.ts +17 -0
- package/dist/components/RichTextEditor/Extension/List/dynamic-bullet-styling.extension.d.ts +2 -0
- package/dist/components/RichTextEditor/Extension/batch-segment-images.extension.d.ts +19 -0
- package/dist/components/RichTextEditor/Extension/batch-segment-images.types.d.ts +33 -0
- package/dist/components/RichTextEditor/Extension/custom-image.extension.d.ts +4 -0
- package/dist/components/RichTextEditor/Extension/custom-link.extension.d.ts +3 -0
- package/dist/components/RichTextEditor/Extension/custom-mention.extension.d.ts +3 -0
- package/dist/components/RichTextEditor/Extension/custom-paragraph.extension.d.ts +6 -0
- package/dist/components/RichTextEditor/Extension/extensions.d.ts +4 -0
- package/dist/components/RichTextEditor/Extension/file-filtering.extension.d.ts +1 -0
- package/dist/components/RichTextEditor/Extension/list-indent-integration.extension.d.ts +2 -0
- package/dist/components/RichTextEditor/Extension/mentionstorage.extension.d.ts +9 -0
- package/dist/components/RichTextEditor/Extension/tiptap-extension-fontsize.d.ts +21 -0
- package/dist/components/RichTextEditor/Extension/tiptap-extension-lineheight.d.ts +21 -0
- package/{src/index.ts → dist/index.d.ts} +5 -17
- package/dist/lynqify-ui.js +3264 -0
- package/dist/lynqify-ui.umd.cjs +30 -0
- package/package.json +60 -31
- package/src/components/RichTextEditor/Extension/Indent/backspace.indent.handlers.ts +0 -77
- package/src/components/RichTextEditor/Extension/Indent/indent.extension.ts +0 -285
- package/src/components/RichTextEditor/Extension/Indent/indent.handlers.ts +0 -121
- package/src/components/RichTextEditor/Extension/Indent/indent.utils.ts +0 -8
- package/src/components/RichTextEditor/Extension/Indent/outdent.handlers.ts +0 -71
- package/src/components/RichTextEditor/Extension/Indent/shifttab.indent.handlers.ts +0 -133
- package/src/components/RichTextEditor/Extension/Indent/tab.indent.handlers.ts +0 -103
- package/src/components/RichTextEditor/Extension/List/custom-list-item.extension.ts +0 -107
- package/src/components/RichTextEditor/Extension/List/dynamic-bullet-styling.extension.ts +0 -40
- package/src/components/RichTextEditor/Extension/batch-segment-images.extension.ts +0 -486
- package/src/components/RichTextEditor/Extension/batch-segment-images.types.ts +0 -35
- package/src/components/RichTextEditor/Extension/custom-image.extension.ts +0 -18
- package/src/components/RichTextEditor/Extension/custom-link.extension.ts +0 -58
- package/src/components/RichTextEditor/Extension/custom-mention.extension.ts +0 -29
- package/src/components/RichTextEditor/Extension/custom-paragraph.extension.ts +0 -46
- package/src/components/RichTextEditor/Extension/extensions.ts +0 -118
- package/src/components/RichTextEditor/Extension/file-filtering.extension.ts +0 -0
- package/src/components/RichTextEditor/Extension/list-indent-integration.extension.ts +0 -125
- package/src/components/RichTextEditor/Extension/mentionstorage.extension.ts +0 -10
- package/src/components/RichTextEditor/Extension/tiptap-extension-fontsize.ts +0 -73
- package/src/components/RichTextEditor/Extension/tiptap-extension-lineheight.ts +0 -73
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import { ShortcutHandler, isListParent, isList, isTextNode } from './indent.types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* WHY: When a user highlights across multiple lines or list items,
|
|
5
|
-
* we want to bulk-increase their indentation level as a group.
|
|
6
|
-
*/
|
|
7
|
-
export const handleTabMultiNodeSelection: ShortcutHandler = ({
|
|
8
|
-
state,
|
|
9
|
-
view,
|
|
10
|
-
$from,
|
|
11
|
-
$to,
|
|
12
|
-
selectionIsEmpty,
|
|
13
|
-
}) => {
|
|
14
|
-
if (selectionIsEmpty) return false;
|
|
15
|
-
|
|
16
|
-
let selectedIndentableNodesCount = 0;
|
|
17
|
-
state.doc.nodesBetween($from.pos, $to.pos, (node: any) => {
|
|
18
|
-
if (isList(node.type.name) || isTextNode(node.type.name)) {
|
|
19
|
-
selectedIndentableNodesCount++;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
const isMultiNodeSelection = selectedIndentableNodesCount > 1;
|
|
24
|
-
if (!isMultiNodeSelection) return false;
|
|
25
|
-
|
|
26
|
-
const { tr, doc } = state;
|
|
27
|
-
let hasAppliedAnyIndent = false;
|
|
28
|
-
const processedListPositions = new Set<number>();
|
|
29
|
-
|
|
30
|
-
doc.nodesBetween($from.pos, $to.pos, (node: any, pos: number) => {
|
|
31
|
-
const isTargetNode = isListParent(node.type.name) || isTextNode(node.type.name);
|
|
32
|
-
|
|
33
|
-
if (isTargetNode && !processedListPositions.has(pos)) {
|
|
34
|
-
processedListPositions.add(pos);
|
|
35
|
-
const currentIndent = node.attrs.indent ?? 0;
|
|
36
|
-
tr.setNodeAttribute(pos, 'indent', currentIndent + 1);
|
|
37
|
-
hasAppliedAnyIndent = true;
|
|
38
|
-
return false; // Prevent recursing into children of processed nodes
|
|
39
|
-
}
|
|
40
|
-
return true;
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
if (hasAppliedAnyIndent) {
|
|
44
|
-
tr.setMeta('addToHistory', true);
|
|
45
|
-
view.dispatch(tr);
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return false;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* WHY: If a user has highlighted a specific word or phrase inside a single text line,
|
|
54
|
-
* pressing Tab shouldn't move the entire line layout. It should just overwrite the text with a \t.
|
|
55
|
-
*/
|
|
56
|
-
export const handleTabSingleNodeTextSelection: ShortcutHandler = ({
|
|
57
|
-
state,
|
|
58
|
-
view,
|
|
59
|
-
$from,
|
|
60
|
-
selectionIsEmpty,
|
|
61
|
-
}) => {
|
|
62
|
-
if (selectionIsEmpty) return false;
|
|
63
|
-
|
|
64
|
-
// WHY: A selection inside a list item should indent the list, not insert a literal tab.
|
|
65
|
-
const isInsideList = $from.path.some((entry: any) => entry?.type?.name === 'listItem');
|
|
66
|
-
if (isInsideList) return false;
|
|
67
|
-
|
|
68
|
-
view.dispatch(state.tr.insertText('\t'));
|
|
69
|
-
return true;
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* WHY: If the user is currently typing inside a List Item but they haven't highlighted anything,
|
|
74
|
-
* let the List extension handle indenting structurally.
|
|
75
|
-
*/
|
|
76
|
-
export const handleTabInsideListItem: ShortcutHandler = ({ editor, currentNode, $from }) => {
|
|
77
|
-
const isLineEmpty = currentNode.content.size === 0;
|
|
78
|
-
const parentNode = $from.node($from.depth - 1);
|
|
79
|
-
const isInsideListItem = parentNode && isList(parentNode.type.name);
|
|
80
|
-
|
|
81
|
-
if (isInsideListItem && !isLineEmpty) {
|
|
82
|
-
editor.chain().focus().indent().focus().run();
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return false;
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* WHY: If the cursor is right in the middle of a sentence, inject a literal Tab character.
|
|
91
|
-
* We only block-indent the whole line if the cursor is at the very beginning.
|
|
92
|
-
*/
|
|
93
|
-
export const handleTabMidTextCursor: ShortcutHandler = ({ state, view, $from, currentNode }) => {
|
|
94
|
-
const isCursorAtStart = $from.pos === $from.start();
|
|
95
|
-
const isLineEmpty = currentNode.content.size === 0;
|
|
96
|
-
|
|
97
|
-
if (!isCursorAtStart && !isLineEmpty) {
|
|
98
|
-
view.dispatch(state.tr.insertText('\t'));
|
|
99
|
-
return true;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return false;
|
|
103
|
-
};
|
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom List Extensions: Indent Attribute Support
|
|
3
|
-
*
|
|
4
|
-
* Extends TipTap list nodes (BulletList, OrderedList, ListItem) with indent attributes.
|
|
5
|
-
*
|
|
6
|
-
* Per FR-020: ListItem receives transferred indent from paragraph
|
|
7
|
-
* Per FR-021: Paragraph children inside lists must NOT have indent
|
|
8
|
-
* Per FR-022: List-level indent separate from item indent
|
|
9
|
-
* Per FR-030: Backward compatibility via attribute defaults
|
|
10
|
-
*
|
|
11
|
-
* @see specs/001-richtext-indent-lists/data-model.md
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
import BulletList from '@tiptap/extension-bullet-list';
|
|
15
|
-
import ListItem from '@tiptap/extension-list-item';
|
|
16
|
-
import OrderedList from '@tiptap/extension-ordered-list';
|
|
17
|
-
|
|
18
|
-
// CONVENTION - T009: Extend BulletList with indent attribute (FR-022)
|
|
19
|
-
export const CustomBulletList = BulletList.extend({
|
|
20
|
-
addAttributes() {
|
|
21
|
-
return {
|
|
22
|
-
...this.parent?.(),
|
|
23
|
-
indent: {
|
|
24
|
-
default: 0, // Backward compatibility (FR-030)
|
|
25
|
-
parseHTML: (element) => parseInt(element.getAttribute('data-indent') || '0', 10),
|
|
26
|
-
renderHTML: (attributes) => {
|
|
27
|
-
if (!attributes.indent) return {};
|
|
28
|
-
return { 'data-indent': attributes.indent };
|
|
29
|
-
},
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
addNodeView() {
|
|
35
|
-
return ({ node }) => {
|
|
36
|
-
const indentLevel = node.attrs.indent || 0;
|
|
37
|
-
const dom = document.createElement('ul');
|
|
38
|
-
dom.setAttribute('data-indent', String(indentLevel));
|
|
39
|
-
|
|
40
|
-
// Apply padding based on indent level (20px per level)
|
|
41
|
-
if (indentLevel > 0) {
|
|
42
|
-
dom.style.paddingLeft = `${indentLevel * 20}px`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const contentDOM = dom;
|
|
46
|
-
return { dom, contentDOM };
|
|
47
|
-
};
|
|
48
|
-
},
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
// CONVENTION - T010: Extend OrderedList with indent attribute (FR-022)
|
|
52
|
-
export const CustomOrderedList = OrderedList.extend({
|
|
53
|
-
addAttributes() {
|
|
54
|
-
return {
|
|
55
|
-
...this.parent?.(),
|
|
56
|
-
indent: {
|
|
57
|
-
default: 0, // Backward compatibility (FR-030)
|
|
58
|
-
parseHTML: (element) => parseInt(element.getAttribute('data-indent') || '0', 10),
|
|
59
|
-
renderHTML: (attributes) => {
|
|
60
|
-
if (!attributes.indent) return {};
|
|
61
|
-
return { 'data-indent': attributes.indent };
|
|
62
|
-
},
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
},
|
|
66
|
-
|
|
67
|
-
addNodeView() {
|
|
68
|
-
return ({ node }) => {
|
|
69
|
-
const indentLevel = node.attrs.indent || 0;
|
|
70
|
-
const dom = document.createElement('ol');
|
|
71
|
-
dom.setAttribute('data-indent', String(indentLevel));
|
|
72
|
-
|
|
73
|
-
// Apply padding based on indent level (20px per level)
|
|
74
|
-
if (indentLevel > 0) {
|
|
75
|
-
dom.style.paddingLeft = `${indentLevel * 20}px`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const contentDOM = dom;
|
|
79
|
-
return { dom, contentDOM };
|
|
80
|
-
};
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
// CONVENTION - T011: Extend ListItem with indent attribute (FR-020, FR-021)
|
|
85
|
-
export const CustomListItem = ListItem.extend({
|
|
86
|
-
addAttributes() {
|
|
87
|
-
return {
|
|
88
|
-
...this.parent?.(),
|
|
89
|
-
class: {
|
|
90
|
-
default: null,
|
|
91
|
-
parseHTML: (element: any) => element.getAttribute('class'),
|
|
92
|
-
renderHTML: (attributes: any) => {
|
|
93
|
-
if (!attributes.class) return {};
|
|
94
|
-
return { class: attributes.class, ...attributes };
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
indent: {
|
|
98
|
-
default: 0, // Backward compatibility (FR-030)
|
|
99
|
-
parseHTML: (element) => parseInt(element.getAttribute('data-indent') || '0', 10),
|
|
100
|
-
renderHTML: (attributes) => {
|
|
101
|
-
if (!attributes.indent) return {};
|
|
102
|
-
return { 'data-indent': attributes.indent };
|
|
103
|
-
},
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
},
|
|
107
|
-
});
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Extension } from '@tiptap/core';
|
|
2
|
-
import { Plugin, PluginKey } from 'prosemirror-state';
|
|
3
|
-
|
|
4
|
-
// Dynamic bullet styling extension (assigns class based on nesting level)
|
|
5
|
-
export const DynamicBulletStyling = Extension.create({
|
|
6
|
-
name: 'dynamicBulletStyling',
|
|
7
|
-
addProseMirrorPlugins() {
|
|
8
|
-
return [
|
|
9
|
-
new Plugin({
|
|
10
|
-
key: new PluginKey('dynamicBulletStyling'),
|
|
11
|
-
appendTransaction: (transactions, oldState, newState) => {
|
|
12
|
-
const tr = newState.tr;
|
|
13
|
-
let modified = false;
|
|
14
|
-
newState.doc.descendants((node, pos) => {
|
|
15
|
-
if (node.type.name === 'listItem') {
|
|
16
|
-
let nestingLevel = 0;
|
|
17
|
-
|
|
18
|
-
const $pos = newState.doc.resolve(pos);
|
|
19
|
-
|
|
20
|
-
for (let depth = $pos.depth; depth > 0; depth--) {
|
|
21
|
-
const nodeAtDepth = $pos.node(depth);
|
|
22
|
-
if (nodeAtDepth.type.name === 'bulletList') {
|
|
23
|
-
nestingLevel = 1;
|
|
24
|
-
break;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (nestingLevel > 0) {
|
|
29
|
-
tr.setNodeAttribute($pos.pos, '[data-style]', 'line-height: inherit');
|
|
30
|
-
// tr.setDocAttribute('[data-style]', 'line-height: inherit');
|
|
31
|
-
modified = true;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
return modified ? tr : null;
|
|
36
|
-
},
|
|
37
|
-
}),
|
|
38
|
-
];
|
|
39
|
-
},
|
|
40
|
-
});
|