react-native-richify 1.0.0
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/LICENSE +21 -0
- package/README.md +231 -0
- package/lib/commonjs/components/OverlayText.d.js +6 -0
- package/lib/commonjs/components/OverlayText.d.js.map +1 -0
- package/lib/commonjs/components/OverlayText.js +45 -0
- package/lib/commonjs/components/OverlayText.js.map +1 -0
- package/lib/commonjs/components/RichTextInput.d.js +6 -0
- package/lib/commonjs/components/RichTextInput.d.js.map +1 -0
- package/lib/commonjs/components/RichTextInput.js +160 -0
- package/lib/commonjs/components/RichTextInput.js.map +1 -0
- package/lib/commonjs/components/Toolbar.d.js +6 -0
- package/lib/commonjs/components/Toolbar.d.js.map +1 -0
- package/lib/commonjs/components/Toolbar.js +99 -0
- package/lib/commonjs/components/Toolbar.js.map +1 -0
- package/lib/commonjs/components/ToolbarButton.d.js +6 -0
- package/lib/commonjs/components/ToolbarButton.d.js.map +1 -0
- package/lib/commonjs/components/ToolbarButton.js +63 -0
- package/lib/commonjs/components/ToolbarButton.js.map +1 -0
- package/lib/commonjs/constants/defaultStyles.d.js +6 -0
- package/lib/commonjs/constants/defaultStyles.d.js.map +1 -0
- package/lib/commonjs/constants/defaultStyles.js +172 -0
- package/lib/commonjs/constants/defaultStyles.js.map +1 -0
- package/lib/commonjs/context/RichTextContext.d.js +6 -0
- package/lib/commonjs/context/RichTextContext.d.js.map +1 -0
- package/lib/commonjs/context/RichTextContext.js +61 -0
- package/lib/commonjs/context/RichTextContext.js.map +1 -0
- package/lib/commonjs/hooks/useFormatting.d.js +6 -0
- package/lib/commonjs/hooks/useFormatting.d.js.map +1 -0
- package/lib/commonjs/hooks/useFormatting.js +82 -0
- package/lib/commonjs/hooks/useFormatting.js.map +1 -0
- package/lib/commonjs/hooks/useRichText.d.js +6 -0
- package/lib/commonjs/hooks/useRichText.d.js.map +1 -0
- package/lib/commonjs/hooks/useRichText.js +136 -0
- package/lib/commonjs/hooks/useRichText.js.map +1 -0
- package/lib/commonjs/hooks/useSelection.d.js +6 -0
- package/lib/commonjs/hooks/useSelection.d.js.map +1 -0
- package/lib/commonjs/hooks/useSelection.js +39 -0
- package/lib/commonjs/hooks/useSelection.js.map +1 -0
- package/lib/commonjs/index.d.js +186 -0
- package/lib/commonjs/index.d.js.map +1 -0
- package/lib/commonjs/index.js +186 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types/index.d.js +6 -0
- package/lib/commonjs/types/index.d.js.map +1 -0
- package/lib/commonjs/types/index.js +6 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/utils/formatter.d.js +13 -0
- package/lib/commonjs/utils/formatter.d.js.map +1 -0
- package/lib/commonjs/utils/formatter.js +229 -0
- package/lib/commonjs/utils/formatter.js.map +1 -0
- package/lib/commonjs/utils/parser.d.js +6 -0
- package/lib/commonjs/utils/parser.d.js.map +1 -0
- package/lib/commonjs/utils/parser.js +221 -0
- package/lib/commonjs/utils/parser.js.map +1 -0
- package/lib/commonjs/utils/styleMapper.d.js +6 -0
- package/lib/commonjs/utils/styleMapper.d.js.map +1 -0
- package/lib/commonjs/utils/styleMapper.js +87 -0
- package/lib/commonjs/utils/styleMapper.js.map +1 -0
- package/lib/module/components/OverlayText.d.js +4 -0
- package/lib/module/components/OverlayText.d.js.map +1 -0
- package/lib/module/components/OverlayText.js +41 -0
- package/lib/module/components/OverlayText.js.map +1 -0
- package/lib/module/components/RichTextInput.d.js +4 -0
- package/lib/module/components/RichTextInput.d.js.map +1 -0
- package/lib/module/components/RichTextInput.js +155 -0
- package/lib/module/components/RichTextInput.js.map +1 -0
- package/lib/module/components/Toolbar.d.js +4 -0
- package/lib/module/components/Toolbar.d.js.map +1 -0
- package/lib/module/components/Toolbar.js +95 -0
- package/lib/module/components/Toolbar.js.map +1 -0
- package/lib/module/components/ToolbarButton.d.js +4 -0
- package/lib/module/components/ToolbarButton.d.js.map +1 -0
- package/lib/module/components/ToolbarButton.js +59 -0
- package/lib/module/components/ToolbarButton.js.map +1 -0
- package/lib/module/constants/defaultStyles.d.js +4 -0
- package/lib/module/constants/defaultStyles.d.js.map +1 -0
- package/lib/module/constants/defaultStyles.js +168 -0
- package/lib/module/constants/defaultStyles.js.map +1 -0
- package/lib/module/context/RichTextContext.d.js +4 -0
- package/lib/module/context/RichTextContext.d.js.map +1 -0
- package/lib/module/context/RichTextContext.js +55 -0
- package/lib/module/context/RichTextContext.js.map +1 -0
- package/lib/module/hooks/useFormatting.d.js +11 -0
- package/lib/module/hooks/useFormatting.d.js.map +1 -0
- package/lib/module/hooks/useFormatting.js +78 -0
- package/lib/module/hooks/useFormatting.js.map +1 -0
- package/lib/module/hooks/useRichText.d.js +4 -0
- package/lib/module/hooks/useRichText.d.js.map +1 -0
- package/lib/module/hooks/useRichText.js +132 -0
- package/lib/module/hooks/useRichText.js.map +1 -0
- package/lib/module/hooks/useSelection.d.js +4 -0
- package/lib/module/hooks/useSelection.d.js.map +1 -0
- package/lib/module/hooks/useSelection.js +35 -0
- package/lib/module/hooks/useSelection.js.map +1 -0
- package/lib/module/index.d.js +15 -0
- package/lib/module/index.d.js.map +1 -0
- package/lib/module/index.js +25 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/types/index.d.js +4 -0
- package/lib/module/types/index.d.js.map +1 -0
- package/lib/module/types/index.js +4 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/utils/formatter.d.js +30 -0
- package/lib/module/utils/formatter.d.js.map +1 -0
- package/lib/module/utils/formatter.js +217 -0
- package/lib/module/utils/formatter.js.map +1 -0
- package/lib/module/utils/parser.d.js +4 -0
- package/lib/module/utils/parser.d.js.map +1 -0
- package/lib/module/utils/parser.js +211 -0
- package/lib/module/utils/parser.js.map +1 -0
- package/lib/module/utils/styleMapper.d.js +4 -0
- package/lib/module/utils/styleMapper.d.js.map +1 -0
- package/lib/module/utils/styleMapper.js +82 -0
- package/lib/module/utils/styleMapper.js.map +1 -0
- package/lib/typescript/src/components/OverlayText.d.ts +11 -0
- package/lib/typescript/src/components/OverlayText.d.ts.map +1 -0
- package/lib/typescript/src/components/RichTextInput.d.ts +21 -0
- package/lib/typescript/src/components/RichTextInput.d.ts.map +1 -0
- package/lib/typescript/src/components/Toolbar.d.ts +13 -0
- package/lib/typescript/src/components/Toolbar.d.ts.map +1 -0
- package/lib/typescript/src/components/ToolbarButton.d.ts +8 -0
- package/lib/typescript/src/components/ToolbarButton.d.ts.map +1 -0
- package/lib/typescript/src/constants/defaultStyles.d.ts +46 -0
- package/lib/typescript/src/constants/defaultStyles.d.ts.map +1 -0
- package/lib/typescript/src/context/RichTextContext.d.ts +31 -0
- package/lib/typescript/src/context/RichTextContext.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useFormatting.d.ts +26 -0
- package/lib/typescript/src/hooks/useFormatting.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useRichText.d.ts +17 -0
- package/lib/typescript/src/hooks/useRichText.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useSelection.d.ts +14 -0
- package/lib/typescript/src/hooks/useSelection.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +16 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/types/index.d.ts +245 -0
- package/lib/typescript/src/types/index.d.ts.map +1 -0
- package/lib/typescript/src/utils/formatter.d.ts +29 -0
- package/lib/typescript/src/utils/formatter.d.ts.map +1 -0
- package/lib/typescript/src/utils/parser.d.ts +46 -0
- package/lib/typescript/src/utils/parser.d.ts.map +1 -0
- package/lib/typescript/src/utils/styleMapper.d.ts +16 -0
- package/lib/typescript/src/utils/styleMapper.d.ts.map +1 -0
- package/package.json +83 -0
- package/src/components/OverlayText.d.ts +10 -0
- package/src/components/OverlayText.tsx +46 -0
- package/src/components/RichTextInput.d.ts +20 -0
- package/src/components/RichTextInput.tsx +174 -0
- package/src/components/Toolbar.d.ts +12 -0
- package/src/components/Toolbar.tsx +100 -0
- package/src/components/ToolbarButton.d.ts +7 -0
- package/src/components/ToolbarButton.tsx +65 -0
- package/src/constants/defaultStyles.d.ts +45 -0
- package/src/constants/defaultStyles.ts +144 -0
- package/src/context/RichTextContext.d.ts +30 -0
- package/src/context/RichTextContext.tsx +63 -0
- package/src/hooks/useFormatting.d.ts +25 -0
- package/src/hooks/useFormatting.ts +135 -0
- package/src/hooks/useRichText.d.ts +16 -0
- package/src/hooks/useRichText.ts +171 -0
- package/src/hooks/useSelection.d.ts +13 -0
- package/src/hooks/useSelection.ts +40 -0
- package/src/index.d.ts +15 -0
- package/src/index.ts +68 -0
- package/src/types/index.d.ts +244 -0
- package/src/types/index.ts +295 -0
- package/src/utils/formatter.d.ts +28 -0
- package/src/utils/formatter.ts +276 -0
- package/src/utils/parser.d.ts +45 -0
- package/src/utils/parser.ts +252 -0
- package/src/utils/styleMapper.d.ts +15 -0
- package/src/utils/styleMapper.ts +92 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { EMPTY_FORMAT_STYLE } from '@/constants/defaultStyles';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a new segment with the given text and optional styles.
|
|
7
|
+
*/
|
|
8
|
+
export function createSegment(text, styles = {
|
|
9
|
+
...EMPTY_FORMAT_STYLE
|
|
10
|
+
}) {
|
|
11
|
+
return {
|
|
12
|
+
text,
|
|
13
|
+
styles: {
|
|
14
|
+
...styles
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Computes the total character length across all segments.
|
|
21
|
+
*/
|
|
22
|
+
export function getTotalLength(segments) {
|
|
23
|
+
return segments.reduce((sum, seg) => sum + seg.text.length, 0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Converts an array of segments to plain text.
|
|
28
|
+
*/
|
|
29
|
+
export function segmentsToPlainText(segments) {
|
|
30
|
+
return segments.map(s => s.text).join('');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Finds which segment and character offset a global position corresponds to.
|
|
35
|
+
* Returns { segmentIndex, offsetInSegment }.
|
|
36
|
+
*/
|
|
37
|
+
export function findPositionInSegments(segments, globalPosition) {
|
|
38
|
+
let remaining = globalPosition;
|
|
39
|
+
for (let i = 0; i < segments.length; i++) {
|
|
40
|
+
const segLen = segments[i].text.length;
|
|
41
|
+
if (remaining <= segLen) {
|
|
42
|
+
return {
|
|
43
|
+
segmentIndex: i,
|
|
44
|
+
offsetInSegment: remaining
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
remaining -= segLen;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Position is past the end — return end of last segment
|
|
51
|
+
const lastIndex = Math.max(0, segments.length - 1);
|
|
52
|
+
return {
|
|
53
|
+
segmentIndex: lastIndex,
|
|
54
|
+
offsetInSegment: segments.length > 0 ? segments[lastIndex].text.length : 0
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Splits a segment at the given offset, returning [before, after].
|
|
60
|
+
* If offset is 0 or at end, one side will have empty text.
|
|
61
|
+
*/
|
|
62
|
+
export function splitSegment(segment, offset) {
|
|
63
|
+
const before = createSegment(segment.text.slice(0, offset), segment.styles);
|
|
64
|
+
const after = createSegment(segment.text.slice(offset), segment.styles);
|
|
65
|
+
return [before, after];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Checks if two FormatStyle objects are deeply equal.
|
|
70
|
+
*/
|
|
71
|
+
export function areStylesEqual(a, b) {
|
|
72
|
+
return !!a.bold === !!b.bold && !!a.italic === !!b.italic && !!a.underline === !!b.underline && !!a.strikethrough === !!b.strikethrough && !!a.code === !!b.code && (a.color ?? undefined) === (b.color ?? undefined) && (a.backgroundColor ?? undefined) === (b.backgroundColor ?? undefined) && (a.fontSize ?? undefined) === (b.fontSize ?? undefined) && (a.heading ?? undefined) === (b.heading ?? undefined);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Merges adjacent segments that have identical styles.
|
|
77
|
+
* Returns a new array (does not mutate input).
|
|
78
|
+
*/
|
|
79
|
+
export function mergeAdjacentSegments(segments) {
|
|
80
|
+
if (segments.length === 0) {
|
|
81
|
+
return [createSegment('')];
|
|
82
|
+
}
|
|
83
|
+
const result = [];
|
|
84
|
+
let last = null;
|
|
85
|
+
for (const seg of segments) {
|
|
86
|
+
// Empty segment → acts as boundary
|
|
87
|
+
if (seg.text.length === 0) {
|
|
88
|
+
last = null; // break merge chain
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
if (last && areStylesEqual(last.styles, seg.styles)) {
|
|
92
|
+
last.text += seg.text;
|
|
93
|
+
} else {
|
|
94
|
+
const newSeg = createSegment(seg.text, seg.styles);
|
|
95
|
+
result.push(newSeg);
|
|
96
|
+
last = newSeg;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// If everything was empty
|
|
101
|
+
if (result.length === 0) {
|
|
102
|
+
return [createSegment('')];
|
|
103
|
+
}
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Given the old segments and new plain text (from TextInput onChange),
|
|
109
|
+
* reconcile the segments to preserve formatting while reflecting the text change.
|
|
110
|
+
*
|
|
111
|
+
* Strategy:
|
|
112
|
+
* 1. Find the diff region between old plain text and new plain text
|
|
113
|
+
* 2. Replace that region in the segment array
|
|
114
|
+
* 3. New text inserted at the diff point inherits the `activeStyles`
|
|
115
|
+
*/
|
|
116
|
+
export function reconcileTextChange(oldSegments, newText, activeStyles) {
|
|
117
|
+
const oldText = segmentsToPlainText(oldSegments);
|
|
118
|
+
if (newText === oldText) {
|
|
119
|
+
return oldSegments;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Find common prefix length
|
|
123
|
+
let prefixLen = 0;
|
|
124
|
+
const minLen = Math.min(oldText.length, newText.length);
|
|
125
|
+
while (prefixLen < minLen && oldText[prefixLen] === newText[prefixLen]) {
|
|
126
|
+
prefixLen++;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Find common suffix length (from end, but not overlapping with prefix)
|
|
130
|
+
let suffixLen = 0;
|
|
131
|
+
while (suffixLen < minLen - prefixLen && oldText[oldText.length - 1 - suffixLen] === newText[newText.length - 1 - suffixLen]) {
|
|
132
|
+
suffixLen++;
|
|
133
|
+
}
|
|
134
|
+
const deleteStart = prefixLen;
|
|
135
|
+
const deleteEnd = oldText.length - suffixLen;
|
|
136
|
+
const insertedText = newText.slice(prefixLen, newText.length - suffixLen);
|
|
137
|
+
|
|
138
|
+
// Build new segments
|
|
139
|
+
// 1. Keep segments before deleteStart
|
|
140
|
+
// 2. Insert new text segment with activeStyles
|
|
141
|
+
// 3. Keep segments after deleteEnd
|
|
142
|
+
|
|
143
|
+
const result = [];
|
|
144
|
+
let pos = 0;
|
|
145
|
+
let phase = 'before';
|
|
146
|
+
let insertedNewSegment = false;
|
|
147
|
+
for (const seg of oldSegments) {
|
|
148
|
+
const segStart = pos;
|
|
149
|
+
const segEnd = pos + seg.text.length;
|
|
150
|
+
if (phase === 'before') {
|
|
151
|
+
if (segEnd <= deleteStart) {
|
|
152
|
+
// Entire segment is before delete region
|
|
153
|
+
result.push(createSegment(seg.text, seg.styles));
|
|
154
|
+
} else if (segStart < deleteStart) {
|
|
155
|
+
// Segment partially before delete region
|
|
156
|
+
result.push(createSegment(seg.text.slice(0, deleteStart - segStart), seg.styles));
|
|
157
|
+
if (!insertedNewSegment && insertedText.length > 0) {
|
|
158
|
+
result.push(createSegment(insertedText, activeStyles));
|
|
159
|
+
insertedNewSegment = true;
|
|
160
|
+
}
|
|
161
|
+
if (segEnd > deleteEnd) {
|
|
162
|
+
// Segment also extends past delete region
|
|
163
|
+
result.push(createSegment(seg.text.slice(deleteEnd - segStart), seg.styles));
|
|
164
|
+
phase = 'after';
|
|
165
|
+
} else {
|
|
166
|
+
phase = 'during';
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
// segStart >= deleteStart → we've reached the delete region
|
|
170
|
+
if (!insertedNewSegment && insertedText.length > 0) {
|
|
171
|
+
result.push(createSegment(insertedText, activeStyles));
|
|
172
|
+
insertedNewSegment = true;
|
|
173
|
+
}
|
|
174
|
+
if (segEnd <= deleteEnd) {
|
|
175
|
+
// Entire segment is within delete region — skip it
|
|
176
|
+
phase = segEnd === deleteEnd ? 'after' : 'during';
|
|
177
|
+
} else {
|
|
178
|
+
// Segment extends past delete region
|
|
179
|
+
result.push(createSegment(seg.text.slice(deleteEnd - segStart), seg.styles));
|
|
180
|
+
phase = 'after';
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} else if (phase === 'during') {
|
|
184
|
+
if (!insertedNewSegment && insertedText.length > 0) {
|
|
185
|
+
result.push(createSegment(insertedText, activeStyles));
|
|
186
|
+
insertedNewSegment = true;
|
|
187
|
+
}
|
|
188
|
+
if (segEnd <= deleteEnd) {
|
|
189
|
+
// Still in delete region — skip
|
|
190
|
+
if (segEnd === deleteEnd) {
|
|
191
|
+
phase = 'after';
|
|
192
|
+
}
|
|
193
|
+
} else {
|
|
194
|
+
// Segment extends past delete region
|
|
195
|
+
result.push(createSegment(seg.text.slice(deleteEnd - segStart), seg.styles));
|
|
196
|
+
phase = 'after';
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
// phase === 'after'
|
|
200
|
+
result.push(createSegment(seg.text, seg.styles));
|
|
201
|
+
}
|
|
202
|
+
pos = segEnd;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// If we never inserted the new text (e.g., appending at end)
|
|
206
|
+
if (!insertedNewSegment && insertedText.length > 0) {
|
|
207
|
+
result.push(createSegment(insertedText, activeStyles));
|
|
208
|
+
}
|
|
209
|
+
return mergeAdjacentSegments(result);
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["EMPTY_FORMAT_STYLE","createSegment","text","styles","getTotalLength","segments","reduce","sum","seg","length","segmentsToPlainText","map","s","join","findPositionInSegments","globalPosition","remaining","i","segLen","segmentIndex","offsetInSegment","lastIndex","Math","max","splitSegment","segment","offset","before","slice","after","areStylesEqual","a","b","bold","italic","underline","strikethrough","code","color","undefined","backgroundColor","fontSize","heading","mergeAdjacentSegments","result","last","newSeg","push","reconcileTextChange","oldSegments","newText","activeStyles","oldText","prefixLen","minLen","min","suffixLen","deleteStart","deleteEnd","insertedText","pos","phase","insertedNewSegment","segStart","segEnd"],"sourceRoot":"..\\..\\..\\src","sources":["utils/parser.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"..\\..\\..\\src","sources":["utils/styleMapper.d.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { DEFAULT_THEME, HEADING_FONT_SIZES } from '@/constants/defaultStyles';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Maps a FormatStyle to a React Native TextStyle.
|
|
7
|
+
* Applies formatting properties based on the segment's style.
|
|
8
|
+
*/
|
|
9
|
+
export function formatStyleToTextStyle(formatStyle, theme) {
|
|
10
|
+
const resolvedTheme = theme ?? DEFAULT_THEME;
|
|
11
|
+
const style = {};
|
|
12
|
+
|
|
13
|
+
// Bold
|
|
14
|
+
if (formatStyle.bold) {
|
|
15
|
+
style.fontWeight = 'bold';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// Italic
|
|
19
|
+
if (formatStyle.italic) {
|
|
20
|
+
style.fontStyle = 'italic';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Underline and strikethrough
|
|
24
|
+
if (formatStyle.underline && formatStyle.strikethrough) {
|
|
25
|
+
style.textDecorationLine = 'underline line-through';
|
|
26
|
+
} else if (formatStyle.underline) {
|
|
27
|
+
style.textDecorationLine = 'underline';
|
|
28
|
+
} else if (formatStyle.strikethrough) {
|
|
29
|
+
style.textDecorationLine = 'line-through';
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Code — apply monospace font and background
|
|
33
|
+
if (formatStyle.code) {
|
|
34
|
+
const codeStyle = resolvedTheme.codeStyle ?? DEFAULT_THEME.codeStyle;
|
|
35
|
+
if (codeStyle) {
|
|
36
|
+
Object.assign(style, codeStyle);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Text color
|
|
41
|
+
if (formatStyle.color) {
|
|
42
|
+
style.color = formatStyle.color;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Background color
|
|
46
|
+
if (formatStyle.backgroundColor) {
|
|
47
|
+
style.backgroundColor = formatStyle.backgroundColor;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Font size
|
|
51
|
+
if (formatStyle.fontSize) {
|
|
52
|
+
style.fontSize = formatStyle.fontSize;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Heading — overrides font size and weight
|
|
56
|
+
if (formatStyle.heading && formatStyle.heading !== 'none') {
|
|
57
|
+
style.fontSize = HEADING_FONT_SIZES[formatStyle.heading];
|
|
58
|
+
style.fontWeight = 'bold';
|
|
59
|
+
style.lineHeight = HEADING_FONT_SIZES[formatStyle.heading] * 1.3;
|
|
60
|
+
}
|
|
61
|
+
return style;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Maps an entire segment to its computed TextStyle (base + format).
|
|
66
|
+
*/
|
|
67
|
+
export function segmentToTextStyle(segment, theme) {
|
|
68
|
+
const baseStyle = theme?.baseTextStyle ?? DEFAULT_THEME.baseTextStyle ?? {};
|
|
69
|
+
const formatStyle = formatStyleToTextStyle(segment.styles, theme);
|
|
70
|
+
return {
|
|
71
|
+
...baseStyle,
|
|
72
|
+
...formatStyle
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Batch-maps an array of segments to an array of TextStyles.
|
|
78
|
+
*/
|
|
79
|
+
export function segmentsToTextStyles(segments, theme) {
|
|
80
|
+
return segments.map(seg => segmentToTextStyle(seg, theme));
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=styleMapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DEFAULT_THEME","HEADING_FONT_SIZES","formatStyleToTextStyle","formatStyle","theme","resolvedTheme","style","bold","fontWeight","italic","fontStyle","underline","strikethrough","textDecorationLine","code","codeStyle","Object","assign","color","backgroundColor","fontSize","heading","lineHeight","segmentToTextStyle","segment","baseStyle","baseTextStyle","styles","segmentsToTextStyles","segments","map","seg"],"sourceRoot":"..\\..\\..\\src","sources":["utils/styleMapper.ts"],"mappings":";;AAEA,SAASA,aAAa,EAAEC,kBAAkB,QAAQ,2BAA2B;;AAE7E;AACA;AACA;AACA;AACA,OAAO,SAASC,sBAAsBA,CACpCC,WAAwB,EACxBC,KAAqB,EACV;EACX,MAAMC,aAAa,GAAGD,KAAK,IAAIJ,aAAa;EAC5C,MAAMM,KAAgB,GAAG,CAAC,CAAC;;EAE3B;EACA,IAAIH,WAAW,CAACI,IAAI,EAAE;IACpBD,KAAK,CAACE,UAAU,GAAG,MAAM;EAC3B;;EAEA;EACA,IAAIL,WAAW,CAACM,MAAM,EAAE;IACtBH,KAAK,CAACI,SAAS,GAAG,QAAQ;EAC5B;;EAEA;EACA,IAAIP,WAAW,CAACQ,SAAS,IAAIR,WAAW,CAACS,aAAa,EAAE;IACtDN,KAAK,CAACO,kBAAkB,GAAG,wBAAwB;EACrD,CAAC,MAAM,IAAIV,WAAW,CAACQ,SAAS,EAAE;IAChCL,KAAK,CAACO,kBAAkB,GAAG,WAAW;EACxC,CAAC,MAAM,IAAIV,WAAW,CAACS,aAAa,EAAE;IACpCN,KAAK,CAACO,kBAAkB,GAAG,cAAc;EAC3C;;EAEA;EACA,IAAIV,WAAW,CAACW,IAAI,EAAE;IACpB,MAAMC,SAAS,GAAGV,aAAa,CAACU,SAAS,IAAIf,aAAa,CAACe,SAAS;IACpE,IAAIA,SAAS,EAAE;MACbC,MAAM,CAACC,MAAM,CAACX,KAAK,EAAES,SAAS,CAAC;IACjC;EACF;;EAEA;EACA,IAAIZ,WAAW,CAACe,KAAK,EAAE;IACrBZ,KAAK,CAACY,KAAK,GAAGf,WAAW,CAACe,KAAK;EACjC;;EAEA;EACA,IAAIf,WAAW,CAACgB,eAAe,EAAE;IAC/Bb,KAAK,CAACa,eAAe,GAAGhB,WAAW,CAACgB,eAAe;EACrD;;EAEA;EACA,IAAIhB,WAAW,CAACiB,QAAQ,EAAE;IACxBd,KAAK,CAACc,QAAQ,GAAGjB,WAAW,CAACiB,QAAQ;EACvC;;EAEA;EACA,IAAIjB,WAAW,CAACkB,OAAO,IAAIlB,WAAW,CAACkB,OAAO,KAAK,MAAM,EAAE;IACzDf,KAAK,CAACc,QAAQ,GAAGnB,kBAAkB,CAACE,WAAW,CAACkB,OAAO,CAAC;IACxDf,KAAK,CAACE,UAAU,GAAG,MAAM;IACzBF,KAAK,CAACgB,UAAU,GAAGrB,kBAAkB,CAACE,WAAW,CAACkB,OAAO,CAAC,GAAG,GAAG;EAClE;EAEA,OAAOf,KAAK;AACd;;AAEA;AACA;AACA;AACA,OAAO,SAASiB,kBAAkBA,CAChCC,OAAsB,EACtBpB,KAAqB,EACV;EACX,MAAMqB,SAAS,GAAGrB,KAAK,EAAEsB,aAAa,IAAI1B,aAAa,CAAC0B,aAAa,IAAI,CAAC,CAAC;EAC3E,MAAMvB,WAAW,GAAGD,sBAAsB,CAACsB,OAAO,CAACG,MAAM,EAAEvB,KAAK,CAAC;EAEjE,OAAO;IACL,GAAGqB,SAAS;IACZ,GAAGtB;EACL,CAAC;AACH;;AAEA;AACA;AACA;AACA,OAAO,SAASyB,oBAAoBA,CAClCC,QAAyB,EACzBzB,KAAqB,EACR;EACb,OAAOyB,QAAQ,CAACC,GAAG,CAAEC,GAAG,IAAKR,kBAAkB,CAACQ,GAAG,EAAE3B,KAAK,CAAC,CAAC;AAC9D","ignoreList":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { OverlayTextProps } from '@/types';
|
|
3
|
+
/**
|
|
4
|
+
* OverlayText renders the styled text segments as a `<Text>` component tree.
|
|
5
|
+
*
|
|
6
|
+
* This component is positioned behind the transparent TextInput to create
|
|
7
|
+
* the overlay effect — the user types into the TextInput while seeing
|
|
8
|
+
* the formatted rendering from this component.
|
|
9
|
+
*/
|
|
10
|
+
export declare const OverlayText: React.FC<OverlayTextProps>;
|
|
11
|
+
//# sourceMappingURL=OverlayText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OverlayText.d.ts","sourceRoot":"","sources":["../../../../src/components/OverlayText.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAIhD;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA8BlD,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { RichTextInputProps } from '@/types';
|
|
3
|
+
/**
|
|
4
|
+
* RichTextInput — The main rich text editor component.
|
|
5
|
+
*
|
|
6
|
+
* Uses the Overlay Technique:
|
|
7
|
+
* - A transparent `TextInput` on top captures user input and selection
|
|
8
|
+
* - A styled `<Text>` layer behind it renders the formatted content
|
|
9
|
+
* - Both share identical font metrics for pixel-perfect alignment
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* <RichTextInput
|
|
14
|
+
* placeholder="Start typing..."
|
|
15
|
+
* showToolbar
|
|
16
|
+
* onChangeSegments={(segments) => console.log(segments)}
|
|
17
|
+
* />
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare const RichTextInput: React.FC<RichTextInputProps>;
|
|
21
|
+
//# sourceMappingURL=RichTextInput.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RichTextInput.d.ts","sourceRoot":"","sources":["../../../../src/components/RichTextInput.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiC,MAAM,OAAO,CAAC;AAQtD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAOlD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA6HtD,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ToolbarProps } from '@/types';
|
|
3
|
+
/**
|
|
4
|
+
* Formatting toolbar for the rich text editor.
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - Default toolbar items (bold, italic, underline, etc.)
|
|
8
|
+
* - Custom toolbar items via the `items` prop
|
|
9
|
+
* - Fully custom rendering via `renderToolbar`
|
|
10
|
+
* - Horizontal scrolling for overflow
|
|
11
|
+
*/
|
|
12
|
+
export declare const Toolbar: React.FC<ToolbarProps>;
|
|
13
|
+
//# sourceMappingURL=Toolbar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../../../src/components/Toolbar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAkB,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,YAAY,EAAe,MAAM,SAAS,CAAC;AAIzD;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CA0E1C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ToolbarButtonProps } from '@/types';
|
|
3
|
+
/**
|
|
4
|
+
* A single toolbar button that toggles a formatting option.
|
|
5
|
+
* Supports custom rendering via the `renderButton` prop.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ToolbarButton: React.FC<ToolbarButtonProps>;
|
|
8
|
+
//# sourceMappingURL=ToolbarButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolbarButton.d.ts","sourceRoot":"","sources":["../../../../src/components/ToolbarButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAGlD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAyCtD,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { RichTextTheme, FormatStyle, ToolbarItem } from '@/types';
|
|
2
|
+
/**
|
|
3
|
+
* Default color palette used throughout the editor.
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_COLORS: {
|
|
6
|
+
readonly primary: "#6366F1";
|
|
7
|
+
readonly background: "#FFFFFF";
|
|
8
|
+
readonly text: "#1F2937";
|
|
9
|
+
readonly placeholder: "#9CA3AF";
|
|
10
|
+
readonly toolbarBackground: "#F9FAFB";
|
|
11
|
+
readonly toolbarBorder: "#E5E7EB";
|
|
12
|
+
readonly cursor: "#6366F1";
|
|
13
|
+
readonly activeButtonBg: "#EEF2FF";
|
|
14
|
+
readonly codeBackground: "#F3F4F6";
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Font size presets for heading levels.
|
|
18
|
+
*/
|
|
19
|
+
export declare const HEADING_FONT_SIZES: {
|
|
20
|
+
readonly h1: 32;
|
|
21
|
+
readonly h2: 24;
|
|
22
|
+
readonly h3: 20;
|
|
23
|
+
readonly none: 16;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Default base text style applied to all segments.
|
|
27
|
+
*/
|
|
28
|
+
export declare const DEFAULT_BASE_TEXT_STYLE: {
|
|
29
|
+
readonly fontSize: 16;
|
|
30
|
+
readonly lineHeight: 24;
|
|
31
|
+
readonly color: "#1F2937";
|
|
32
|
+
readonly fontFamily: undefined;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Empty format style — no formatting applied.
|
|
36
|
+
*/
|
|
37
|
+
export declare const EMPTY_FORMAT_STYLE: FormatStyle;
|
|
38
|
+
/**
|
|
39
|
+
* Default theme configuration.
|
|
40
|
+
*/
|
|
41
|
+
export declare const DEFAULT_THEME: RichTextTheme;
|
|
42
|
+
/**
|
|
43
|
+
* Default toolbar items for the built-in toolbar.
|
|
44
|
+
*/
|
|
45
|
+
export declare const DEFAULT_TOOLBAR_ITEMS: ToolbarItem[];
|
|
46
|
+
//# sourceMappingURL=defaultStyles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultStyles.d.ts","sourceRoot":"","sources":["../../../../src/constants/defaultStyles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEvE;;GAEG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;CAUjB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;CAKrB,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;;;CAK1B,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAUhC,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,aA0E3B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,EAS9C,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { UseRichTextReturn } from '@/types';
|
|
3
|
+
import { type UseRichTextOptions } from '@/hooks/useRichText';
|
|
4
|
+
export interface RichTextProviderProps extends UseRichTextOptions {
|
|
5
|
+
children: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* RichTextProvider wraps children with rich text state via React Context.
|
|
9
|
+
*
|
|
10
|
+
* Use this when you need to access the rich text state/actions from
|
|
11
|
+
* deeply nested components (e.g., a custom toolbar in a different part
|
|
12
|
+
* of the component tree).
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <RichTextProvider onChangeSegments={handleChange}>
|
|
17
|
+
* <MyCustomToolbar />
|
|
18
|
+
* <RichTextInput showToolbar={false} />
|
|
19
|
+
* </RichTextProvider>
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export declare const RichTextProvider: React.FC<RichTextProviderProps>;
|
|
23
|
+
/**
|
|
24
|
+
* Hook to access the RichText state and actions from context.
|
|
25
|
+
*
|
|
26
|
+
* Must be used within a `<RichTextProvider>`.
|
|
27
|
+
*
|
|
28
|
+
* @throws If used outside of a RichTextProvider
|
|
29
|
+
*/
|
|
30
|
+
export declare function useRichTextContext(): UseRichTextReturn;
|
|
31
|
+
//# sourceMappingURL=RichTextContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RichTextContext.d.ts","sourceRoot":"","sources":["../../../../src/context/RichTextContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoC,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAkC,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,EAAe,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAQ3E,MAAM,WAAW,qBAAsB,SAAQ,kBAAkB;IAC/D,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAED;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAW5D,CAAC;AAMF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,IAAI,iBAAiB,CAStD"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { StyledSegment, FormatType, FormatStyle, HeadingLevel, SelectionRange } from '@/types';
|
|
2
|
+
interface UseFormattingOptions {
|
|
3
|
+
segments: StyledSegment[];
|
|
4
|
+
selection: SelectionRange;
|
|
5
|
+
activeStyles: FormatStyle;
|
|
6
|
+
onSegmentsChange: (segments: StyledSegment[]) => void;
|
|
7
|
+
onActiveStylesChange: (styles: FormatStyle) => void;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Hook that provides formatting commands for the rich text editor.
|
|
11
|
+
*
|
|
12
|
+
* Handles both selection-based formatting (when text is selected)
|
|
13
|
+
* and active-style updates (when no text is selected — affects next typed text).
|
|
14
|
+
*/
|
|
15
|
+
export declare function useFormatting({ segments, selection, activeStyles, onSegmentsChange, onActiveStylesChange, }: UseFormattingOptions): {
|
|
16
|
+
toggleFormat: (format: FormatType) => void;
|
|
17
|
+
setStyleProperty: <K extends keyof FormatStyle>(key: K, value: FormatStyle[K]) => void;
|
|
18
|
+
setHeading: (level: HeadingLevel) => void;
|
|
19
|
+
setColor: (color: string) => void;
|
|
20
|
+
setBackgroundColor: (color: string) => void;
|
|
21
|
+
setFontSize: (size: number) => void;
|
|
22
|
+
isFormatActive: (format: FormatType) => boolean;
|
|
23
|
+
currentSelectionStyle: () => FormatStyle;
|
|
24
|
+
};
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=useFormatting.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFormatting.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useFormatting.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,WAAW,EACX,YAAY,EACZ,cAAc,EACf,MAAM,SAAS,CAAC;AASjB,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,SAAS,EAAE,cAAc,CAAC;IAC1B,YAAY,EAAE,WAAW,CAAC;IAC1B,gBAAgB,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACtD,oBAAoB,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;CACrD;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,oBAAoB,GACrB,EAAE,oBAAoB;2BAEV,UAAU;uBAqBlB,CAAC,SAAS,MAAM,WAAW,OAAO,CAAC,SAAS,WAAW,CAAC,CAAC,CAAC;wBAoBnD,YAAY;sBAQZ,MAAM;gCAON,MAAM;wBAOP,MAAM;6BAOJ,UAAU,KAAG,OAAO;iCASe,WAAW;EAiB1D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { StyledSegment, UseRichTextReturn } from '@/types';
|
|
2
|
+
export interface UseRichTextOptions {
|
|
3
|
+
/** Initial segments to populate the editor with. */
|
|
4
|
+
initialSegments?: StyledSegment[];
|
|
5
|
+
/** Callback when segments change. */
|
|
6
|
+
onChangeSegments?: (segments: StyledSegment[]) => void;
|
|
7
|
+
/** Callback when plain text changes. */
|
|
8
|
+
onChangeText?: (text: string) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Main hook for the rich text editor.
|
|
12
|
+
*
|
|
13
|
+
* Manages the complete editor state (segments, selection, active styles)
|
|
14
|
+
* and exposes all actions needed to build a rich text UI.
|
|
15
|
+
*/
|
|
16
|
+
export declare function useRichText(options?: UseRichTextOptions): UseRichTextReturn;
|
|
17
|
+
//# sourceMappingURL=useRichText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useRichText.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useRichText.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,aAAa,EAOb,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAWjB,MAAM,WAAW,kBAAkB;IACjC,oDAAoD;IACpD,eAAe,CAAC,EAAE,aAAa,EAAE,CAAC;IAClC,qCAAqC;IACrC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IACvD,wCAAwC;IACxC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAoInB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { SelectionRange } from '@/types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook for tracking TextInput selection state.
|
|
4
|
+
*
|
|
5
|
+
* Returns the current selection and a handler to update it.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useSelection(initialSelection?: SelectionRange): {
|
|
8
|
+
selection: SelectionRange;
|
|
9
|
+
setSelection: import("react").Dispatch<import("react").SetStateAction<SelectionRange>>;
|
|
10
|
+
handleSelectionChange: (newSelection: SelectionRange) => void;
|
|
11
|
+
getSelection: () => SelectionRange;
|
|
12
|
+
hasSelection: () => boolean;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=useSelection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSelection.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useSelection.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,gBAAgB,CAAC,EAAE,cAAc;;;0CAU3C,cAAc;wBAMM,cAAc;wBAId,OAAO;EAW7C"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { RichTextInput } from '@/components/RichTextInput';
|
|
2
|
+
export { OverlayText } from '@/components/OverlayText';
|
|
3
|
+
export { Toolbar } from '@/components/Toolbar';
|
|
4
|
+
export { ToolbarButton } from '@/components/ToolbarButton';
|
|
5
|
+
export { useRichText } from '@/hooks/useRichText';
|
|
6
|
+
export type { UseRichTextOptions } from '@/hooks/useRichText';
|
|
7
|
+
export { useSelection } from '@/hooks/useSelection';
|
|
8
|
+
export { useFormatting } from '@/hooks/useFormatting';
|
|
9
|
+
export { RichTextProvider, useRichTextContext, } from '@/context/RichTextContext';
|
|
10
|
+
export type { RichTextProviderProps } from '@/context/RichTextContext';
|
|
11
|
+
export { createSegment, segmentsToPlainText, getTotalLength, mergeAdjacentSegments, reconcileTextChange, } from '@/utils/parser';
|
|
12
|
+
export { toggleFormatOnSelection, setStyleOnSelection, setHeadingOnLine, isFormatActiveInSelection, getSelectionStyle, } from '@/utils/formatter';
|
|
13
|
+
export { formatStyleToTextStyle, segmentToTextStyle, segmentsToTextStyles, } from '@/utils/styleMapper';
|
|
14
|
+
export { DEFAULT_COLORS, DEFAULT_THEME, DEFAULT_TOOLBAR_ITEMS, DEFAULT_BASE_TEXT_STYLE, HEADING_FONT_SIZES, EMPTY_FORMAT_STYLE, } from '@/constants/defaultStyles';
|
|
15
|
+
export type { FormatType, HeadingLevel, ListType, FormatStyle, StyledSegment, SelectionRange, RichTextState, RichTextActions, UseRichTextReturn, RichTextTheme, ToolbarItem, OverlayTextProps, ToolbarButtonProps, ToolbarProps, RichTextInputProps, } from '@/types';
|
|
16
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAG3D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AACnC,YAAY,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAGvE,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,gBAAgB,EAChB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EACV,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
|