@alpaca-editor/core 1.0.4045 → 1.0.4047
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/editor/field-types/RichTextEditorComponent.js +3 -10
- package/dist/editor/field-types/RichTextEditorComponent.js.map +1 -1
- package/dist/editor/field-types/richtext/components/ReactSlate.js +297 -342
- package/dist/editor/field-types/richtext/components/ReactSlate.js.map +1 -1
- package/dist/editor/field-types/richtext/components/SimpleRichTextEditor.js.map +1 -1
- package/dist/editor/field-types/richtext/components/SimpleToolbar.js +9 -9
- package/dist/editor/field-types/richtext/components/SimpleToolbar.js.map +1 -1
- package/dist/editor/field-types/richtext/config/pluginFactory.d.ts +7 -6
- package/dist/editor/field-types/richtext/config/pluginFactory.js +2 -1
- package/dist/editor/field-types/richtext/config/pluginFactory.js.map +1 -1
- package/dist/editor/field-types/richtext/hooks/useProfileCache.js +24 -18
- package/dist/editor/field-types/richtext/hooks/useProfileCache.js.map +1 -1
- package/dist/editor/field-types/richtext/hooks/useRichTextProfile.js +1 -1
- package/dist/editor/field-types/richtext/hooks/useRichTextProfile.js.map +1 -1
- package/dist/editor/field-types/richtext/types.d.ts +236 -90
- package/dist/editor/field-types/richtext/types.js +3 -3
- package/dist/editor/field-types/richtext/types.js.map +1 -1
- package/dist/editor/field-types/richtext/utils/conversion.d.ts +4 -2
- package/dist/editor/field-types/richtext/utils/conversion.js +79 -12
- package/dist/editor/field-types/richtext/utils/conversion.js.map +1 -1
- package/dist/editor/field-types/richtext/utils/plugins.d.ts +66 -39
- package/dist/editor/field-types/richtext/utils/plugins.js +377 -233
- package/dist/editor/field-types/richtext/utils/plugins.js.map +1 -1
- package/dist/editor/field-types/richtext/utils/profileMapper.js +22 -2
- package/dist/editor/field-types/richtext/utils/profileMapper.js.map +1 -1
- package/dist/revision.d.ts +2 -2
- package/dist/revision.js +2 -2
- package/package.json +1 -1
- package/src/editor/field-types/RichTextEditorComponent.tsx +4 -10
- package/src/editor/field-types/richtext/components/ReactSlate.css +85 -24
- package/src/editor/field-types/richtext/components/ReactSlate.tsx +372 -427
- package/src/editor/field-types/richtext/components/SimpleRichTextEditor.tsx +4 -2
- package/src/editor/field-types/richtext/components/SimpleToolbar.tsx +3 -3
- package/src/editor/field-types/richtext/config/pluginFactory.tsx +2 -1
- package/src/editor/field-types/richtext/hooks/useProfileCache.ts +25 -19
- package/src/editor/field-types/richtext/hooks/useRichTextProfile.ts +1 -1
- package/src/editor/field-types/richtext/types.ts +150 -112
- package/src/editor/field-types/richtext/utils/conversion.ts +100 -27
- package/src/editor/field-types/richtext/utils/plugins.ts +469 -268
- package/src/editor/field-types/richtext/utils/profileMapper.ts +26 -3
- package/src/revision.ts +2 -2
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
SLATE_MARKS,
|
|
12
12
|
SLATE_BLOCKS,
|
|
13
13
|
SLATE_ALIGNMENTS,
|
|
14
|
+
MarkId,
|
|
15
|
+
BlockId,
|
|
14
16
|
} from "../types";
|
|
15
17
|
import { SimpleToolbar } from "./SimpleToolbar";
|
|
16
18
|
import { classNames } from "primereact/utils";
|
|
@@ -97,7 +99,7 @@ export const SimpleRichTextEditor = forwardRef<HTMLDivElement, ReactSlateProps>(
|
|
|
97
99
|
|
|
98
100
|
// Check for active marks
|
|
99
101
|
Object.keys(SLATE_MARKS).forEach((markId) => {
|
|
100
|
-
const markConfig = SLATE_MARKS[markId];
|
|
102
|
+
const markConfig = SLATE_MARKS[markId as MarkId];
|
|
101
103
|
if (document.queryCommandState(getExecCommandForMark(markId))) {
|
|
102
104
|
activeFormats.add(markId);
|
|
103
105
|
}
|
|
@@ -235,7 +237,7 @@ export const SimpleRichTextEditor = forwardRef<HTMLDivElement, ReactSlateProps>(
|
|
|
235
237
|
if (blockId === "no-tag") {
|
|
236
238
|
document.execCommand("formatBlock", false, "div");
|
|
237
239
|
} else {
|
|
238
|
-
const blockConfig = SLATE_BLOCKS[blockId];
|
|
240
|
+
const blockConfig = SLATE_BLOCKS[blockId as BlockId];
|
|
239
241
|
if (blockConfig && blockConfig.htmlTag !== "no-tag") {
|
|
240
242
|
document.execCommand(
|
|
241
243
|
"formatBlock",
|
|
@@ -115,7 +115,7 @@ export const SimpleToolbar: React.FC<SimpleToolbarProps> = ({
|
|
|
115
115
|
onSelect: () => {},
|
|
116
116
|
};
|
|
117
117
|
|
|
118
|
-
case "strip":
|
|
118
|
+
/*case "strip":
|
|
119
119
|
return {
|
|
120
120
|
id: "strip-formatting",
|
|
121
121
|
type: "strip",
|
|
@@ -123,7 +123,7 @@ export const SimpleToolbar: React.FC<SimpleToolbarProps> = ({
|
|
|
123
123
|
icon: "✗",
|
|
124
124
|
isActive: false,
|
|
125
125
|
onSelect: () => stripFormatting(),
|
|
126
|
-
}
|
|
126
|
+
};*/
|
|
127
127
|
|
|
128
128
|
default:
|
|
129
129
|
return null;
|
|
@@ -292,7 +292,7 @@ export const SimpleToolbar: React.FC<SimpleToolbarProps> = ({
|
|
|
292
292
|
acc[row].push(group);
|
|
293
293
|
return acc;
|
|
294
294
|
},
|
|
295
|
-
{} as Record<number,
|
|
295
|
+
{} as Record<number, ToolbarGroupConfig[]>,
|
|
296
296
|
);
|
|
297
297
|
|
|
298
298
|
// Create strip formatting option that's always available
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Editor } from 'slate';
|
|
2
|
-
import { withMark, withBlock, withAlignment, withLink, withList, withNormalization } from '../utils/plugins';
|
|
2
|
+
import { withMark, withBlock, withAlignment, withLink, withList, withNormalization, withInsertion } from '../utils/plugins';
|
|
3
3
|
|
|
4
4
|
// Create plugins from configuration
|
|
5
5
|
export const createPluginsFromConfig = (editor: Editor) => {
|
|
@@ -10,6 +10,7 @@ export const createPluginsFromConfig = (editor: Editor) => {
|
|
|
10
10
|
enhancedEditor = withAlignment(enhancedEditor);
|
|
11
11
|
enhancedEditor = withList(enhancedEditor);
|
|
12
12
|
enhancedEditor = withLink(enhancedEditor);
|
|
13
|
+
enhancedEditor = withInsertion(enhancedEditor);
|
|
13
14
|
|
|
14
15
|
// Add normalization plugin last to ensure it can normalize all other plugin behaviors
|
|
15
16
|
enhancedEditor = withNormalization(enhancedEditor);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useCallback, useMemo } from 'react';
|
|
2
|
-
import { RichTextEditorProfile, SimplifiedProfile } from '../types';
|
|
2
|
+
import { RichTextEditorProfile, SimplifiedProfile, MarkId, BlockId, AlignmentId } from '../types';
|
|
3
3
|
|
|
4
4
|
// Cache for simplified profiles converted from complex profiles
|
|
5
5
|
const simplifiedProfileCache = new Map<string, SimplifiedProfile>();
|
|
@@ -40,49 +40,55 @@ const convertToSimplifiedProfile = (profile: RichTextEditorProfile | null): Simp
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
};
|
|
43
|
+
// Build arrays separately to avoid readonly conflicts
|
|
44
|
+
const marks: MarkId[] = [];
|
|
45
|
+
const blocks: BlockId[] = [];
|
|
46
|
+
const alignment: AlignmentId[] = [];
|
|
47
|
+
let lists = false;
|
|
48
|
+
let links = false;
|
|
50
49
|
|
|
51
50
|
// Extract capabilities from the profile groups
|
|
52
51
|
profile.toolbar.groups.forEach(group => {
|
|
53
52
|
group.options.forEach(option => {
|
|
54
53
|
switch (option.type) {
|
|
55
54
|
case 'mark':
|
|
56
|
-
if (!
|
|
57
|
-
|
|
55
|
+
if (!marks.includes(option.id)) {
|
|
56
|
+
marks.push(option.id);
|
|
58
57
|
}
|
|
59
58
|
break;
|
|
60
59
|
case 'block':
|
|
61
|
-
if (!
|
|
62
|
-
|
|
60
|
+
if (!blocks.includes(option.id)) {
|
|
61
|
+
blocks.push(option.id);
|
|
63
62
|
}
|
|
64
63
|
break;
|
|
65
64
|
case 'alignment':
|
|
66
|
-
if (!
|
|
67
|
-
|
|
65
|
+
if (!alignment.includes(option.id)) {
|
|
66
|
+
alignment.push(option.id);
|
|
68
67
|
}
|
|
69
68
|
break;
|
|
70
69
|
case 'list':
|
|
71
|
-
|
|
70
|
+
lists = true;
|
|
72
71
|
break;
|
|
73
72
|
case 'link':
|
|
74
|
-
|
|
73
|
+
links = true;
|
|
75
74
|
break;
|
|
76
75
|
}
|
|
77
76
|
});
|
|
78
77
|
});
|
|
79
78
|
|
|
80
79
|
// Ensure we have at least one block type
|
|
81
|
-
if (
|
|
82
|
-
|
|
80
|
+
if (blocks.length === 0) {
|
|
81
|
+
blocks.push('paragraph');
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
|
|
84
|
+
// Construct the final object
|
|
85
|
+
return {
|
|
86
|
+
marks,
|
|
87
|
+
blocks,
|
|
88
|
+
alignment,
|
|
89
|
+
lists,
|
|
90
|
+
links
|
|
91
|
+
};
|
|
86
92
|
};
|
|
87
93
|
|
|
88
94
|
/**
|
|
@@ -5,20 +5,71 @@ import { Link } from "../../LinkEditorDialog";
|
|
|
5
5
|
import { HistoryEditor } from "slate-history";
|
|
6
6
|
import { Field } from "../../pageModel";
|
|
7
7
|
|
|
8
|
+
// Strict type definitions for mark IDs
|
|
9
|
+
export type MarkId = keyof typeof SLATE_MARKS;
|
|
10
|
+
export type BlockId = keyof typeof SLATE_BLOCKS;
|
|
11
|
+
export type AlignmentId = keyof typeof SLATE_ALIGNMENTS;
|
|
12
|
+
|
|
13
|
+
// Strict toolbar option types
|
|
14
|
+
export type MarkOptionConfig = {
|
|
15
|
+
readonly type: "mark";
|
|
16
|
+
readonly id: MarkId;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export type BlockOptionConfig = {
|
|
20
|
+
readonly type: "block";
|
|
21
|
+
readonly id: BlockId;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type AlignmentOptionConfig = {
|
|
25
|
+
readonly type: "alignment";
|
|
26
|
+
readonly id: AlignmentId;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type LinkOptionConfig = {
|
|
30
|
+
readonly type: "link";
|
|
31
|
+
readonly id: "link";
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type ListOptionConfig = {
|
|
35
|
+
readonly type: "list";
|
|
36
|
+
readonly id: "unordered-list" | "ordered-list";
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type DividerOptionConfig = {
|
|
40
|
+
readonly type: "divider";
|
|
41
|
+
readonly id: "divider";
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type InsertionOptionConfig = {
|
|
45
|
+
readonly type: "insertion";
|
|
46
|
+
readonly id: "horizontal-rule";
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
// Union type for all possible toolbar options
|
|
50
|
+
export type ToolbarOptionConfig =
|
|
51
|
+
| MarkOptionConfig
|
|
52
|
+
| BlockOptionConfig
|
|
53
|
+
| AlignmentOptionConfig
|
|
54
|
+
| LinkOptionConfig
|
|
55
|
+
| ListOptionConfig
|
|
56
|
+
| DividerOptionConfig
|
|
57
|
+
| InsertionOptionConfig;
|
|
58
|
+
|
|
8
59
|
declare module "slate" {
|
|
9
60
|
interface CustomTypes {
|
|
10
61
|
Editor: BaseEditor &
|
|
11
62
|
ReactEditor &
|
|
12
63
|
HistoryEditor & {
|
|
13
|
-
// Plugin methods
|
|
14
|
-
isMarkActive(format:
|
|
15
|
-
toggleMark(format:
|
|
64
|
+
// Plugin methods with strict typing
|
|
65
|
+
isMarkActive(format: MarkId): boolean;
|
|
66
|
+
toggleMark(format: MarkId): void;
|
|
16
67
|
|
|
17
|
-
isBlockActive(format:
|
|
18
|
-
toggleBlock(format:
|
|
68
|
+
isBlockActive(format: BlockId): boolean;
|
|
69
|
+
toggleBlock(format: BlockId): void;
|
|
19
70
|
|
|
20
|
-
isAlignActive(align:
|
|
21
|
-
toggleAlign(align:
|
|
71
|
+
isAlignActive(align: Alignment): boolean;
|
|
72
|
+
toggleAlign(align: Alignment): void;
|
|
22
73
|
|
|
23
74
|
isLinkActive(): boolean;
|
|
24
75
|
insertLink(options?: {
|
|
@@ -29,132 +80,134 @@ declare module "slate" {
|
|
|
29
80
|
toggleList(listType: "unordered" | "ordered"): void;
|
|
30
81
|
indentList(): void;
|
|
31
82
|
outdentList(): void;
|
|
83
|
+
|
|
84
|
+
insertHorizontalRule(): void;
|
|
32
85
|
};
|
|
33
86
|
Element: CustomElement;
|
|
34
87
|
Text: CustomText;
|
|
35
88
|
}
|
|
36
89
|
}
|
|
37
90
|
|
|
38
|
-
// Custom text type
|
|
91
|
+
// Custom text type with strict mark typing
|
|
39
92
|
export type CustomText = {
|
|
40
|
-
text: string;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
93
|
+
readonly text: string;
|
|
94
|
+
// Mark properties - all optional booleans
|
|
95
|
+
readonly bold?: boolean;
|
|
96
|
+
readonly italic?: boolean;
|
|
97
|
+
readonly underline?: boolean;
|
|
98
|
+
readonly strikethrough?: boolean;
|
|
99
|
+
readonly subscript?: boolean;
|
|
100
|
+
readonly superscript?: boolean;
|
|
101
|
+
readonly extrabold?: boolean;
|
|
102
|
+
readonly isRawHtml?: boolean; // Flag to indicate this text should be preserved as raw HTML
|
|
49
103
|
};
|
|
50
104
|
|
|
51
105
|
export type Alignment = "left" | "center" | "right" | "justify";
|
|
52
106
|
|
|
53
107
|
// Generic element that can have any type
|
|
54
108
|
export type CustomElement = {
|
|
55
|
-
type: string;
|
|
56
|
-
align?: Alignment;
|
|
57
|
-
listType?: "unordered" | "ordered";
|
|
58
|
-
indent?: number;
|
|
59
|
-
children: (CustomText | CustomElement)[];
|
|
60
|
-
[key: string]: any; // For any custom properties
|
|
109
|
+
readonly type: string;
|
|
110
|
+
readonly align?: Alignment;
|
|
111
|
+
readonly listType?: "unordered" | "ordered";
|
|
112
|
+
readonly indent?: number;
|
|
113
|
+
readonly children: readonly (CustomText | CustomElement)[];
|
|
114
|
+
readonly [key: string]: any; // For any custom properties
|
|
61
115
|
};
|
|
62
116
|
|
|
63
117
|
// Preserved element type for unsupported HTML elements
|
|
64
118
|
export type PreservedElement = CustomElement & {
|
|
65
|
-
type: "preserved-element";
|
|
66
|
-
originalTag: string;
|
|
67
|
-
originalHtml: string;
|
|
68
|
-
attributes: Record<string, any>;
|
|
119
|
+
readonly type: "preserved-element";
|
|
120
|
+
readonly originalTag: string;
|
|
121
|
+
readonly originalHtml: string;
|
|
122
|
+
readonly attributes: Record<string, any>;
|
|
69
123
|
};
|
|
70
124
|
|
|
71
125
|
// Preserved inline element type for unsupported inline HTML elements
|
|
72
126
|
export type PreservedInlineElement = CustomElement & {
|
|
73
|
-
type: "preserved-inline";
|
|
74
|
-
originalTag: string;
|
|
75
|
-
originalHtml: string;
|
|
76
|
-
attributes: Record<string, any>;
|
|
127
|
+
readonly type: "preserved-inline";
|
|
128
|
+
readonly originalTag: string;
|
|
129
|
+
readonly originalHtml: string;
|
|
130
|
+
readonly attributes: Record<string, any>;
|
|
77
131
|
};
|
|
78
132
|
|
|
79
133
|
export type LinkElement = CustomElement & {
|
|
80
|
-
type: "link";
|
|
81
|
-
link: Link;
|
|
134
|
+
readonly type: "link";
|
|
135
|
+
readonly link: Link;
|
|
82
136
|
};
|
|
83
137
|
|
|
84
138
|
export interface ReactSlateProps {
|
|
85
|
-
value?: string;
|
|
86
|
-
onChange?: (value: string) => void;
|
|
87
|
-
onFocus?: () => void;
|
|
88
|
-
onBlur?: () => void;
|
|
89
|
-
readOnly?: boolean;
|
|
90
|
-
placeholder?: string;
|
|
91
|
-
className?: string;
|
|
92
|
-
profile?: RichTextEditorProfile;
|
|
139
|
+
readonly value?: string;
|
|
140
|
+
readonly onChange?: (value: string) => void;
|
|
141
|
+
readonly onFocus?: () => void;
|
|
142
|
+
readonly onBlur?: () => void;
|
|
143
|
+
readonly readOnly?: boolean;
|
|
144
|
+
readonly placeholder?: string;
|
|
145
|
+
readonly className?: string;
|
|
146
|
+
readonly profile?: RichTextEditorProfile;
|
|
93
147
|
}
|
|
94
148
|
|
|
149
|
+
// Strict option interface
|
|
95
150
|
export interface CustomOption {
|
|
96
|
-
id: string;
|
|
97
|
-
label?: string;
|
|
98
|
-
icon?: React.ReactNode;
|
|
99
|
-
isActive?: (editor: Editor) => boolean;
|
|
100
|
-
toggle?: (editor: Editor, event: React.MouseEvent) => void;
|
|
151
|
+
readonly id: string;
|
|
152
|
+
readonly label?: string;
|
|
153
|
+
readonly icon?: React.ReactNode;
|
|
154
|
+
readonly isActive?: (editor: Editor) => boolean;
|
|
155
|
+
readonly toggle?: (editor: Editor, event: React.MouseEvent) => void;
|
|
101
156
|
}
|
|
102
157
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
158
|
+
// Strict dropdown option type
|
|
159
|
+
export type DropdownOption<T = CustomOption> = {
|
|
160
|
+
readonly value: T;
|
|
161
|
+
readonly label?: string;
|
|
162
|
+
readonly icon?: React.ReactNode;
|
|
163
|
+
readonly style?: React.CSSProperties;
|
|
164
|
+
readonly isActive: (editor: Editor) => boolean;
|
|
165
|
+
readonly onSelect: (editor: Editor, event: React.MouseEvent) => void;
|
|
110
166
|
};
|
|
111
167
|
|
|
112
168
|
export interface ToolbarButtonProps {
|
|
113
|
-
icon: React.ReactNode;
|
|
114
|
-
active: boolean;
|
|
115
|
-
onMouseDown?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
169
|
+
readonly icon: React.ReactNode;
|
|
170
|
+
readonly active: boolean;
|
|
171
|
+
readonly onMouseDown?: (event: React.MouseEvent<HTMLButtonElement>) => void;
|
|
116
172
|
}
|
|
117
173
|
|
|
174
|
+
// Strict toolbar group configuration
|
|
118
175
|
export interface ToolbarGroupConfig {
|
|
119
|
-
id: string;
|
|
120
|
-
label?: string;
|
|
121
|
-
display?: "buttons" | "dropdown";
|
|
122
|
-
showIconsOnly?: boolean;
|
|
123
|
-
options: ToolbarOptionConfig[];
|
|
124
|
-
row?: number; // Optional row identifier for grouping
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export interface ToolbarOptionConfig {
|
|
128
|
-
type: "mark" | "block" | "alignment" | "link" | "list" | "divider" | string;
|
|
129
|
-
id: string; // Reference to the option in the corresponding collection
|
|
176
|
+
readonly id: string;
|
|
177
|
+
readonly label?: string;
|
|
178
|
+
readonly display?: "buttons" | "dropdown";
|
|
179
|
+
readonly showIconsOnly?: boolean;
|
|
180
|
+
readonly options: readonly ToolbarOptionConfig[];
|
|
181
|
+
readonly row?: number; // Optional row identifier for grouping
|
|
130
182
|
}
|
|
131
183
|
|
|
184
|
+
// Strict profile types
|
|
132
185
|
export type RichTextEditorProfile = {
|
|
133
|
-
toolbar: {
|
|
134
|
-
groups: ToolbarGroupConfig[];
|
|
186
|
+
readonly toolbar: {
|
|
187
|
+
readonly groups: readonly ToolbarGroupConfig[];
|
|
135
188
|
};
|
|
136
189
|
};
|
|
137
190
|
|
|
138
191
|
// Simplified profile structure that maps directly to Slate capabilities
|
|
139
192
|
export interface SimplifiedProfile {
|
|
140
|
-
marks:
|
|
141
|
-
blocks:
|
|
142
|
-
alignment:
|
|
143
|
-
lists: boolean; // true if lists are enabled
|
|
144
|
-
links: boolean; // true if links are enabled
|
|
193
|
+
readonly marks: readonly MarkId[]; // Strict typing for marks
|
|
194
|
+
readonly blocks: readonly BlockId[]; // Strict typing for blocks
|
|
195
|
+
readonly alignment: readonly AlignmentId[]; // Strict typing for alignment
|
|
196
|
+
readonly lists: boolean; // true if lists are enabled
|
|
197
|
+
readonly links: boolean; // true if links are enabled
|
|
145
198
|
}
|
|
146
199
|
|
|
147
|
-
//
|
|
148
|
-
export
|
|
149
|
-
|
|
150
|
-
{
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
200
|
+
// Conversion result types for better error handling
|
|
201
|
+
export type HtmlToSlateResult =
|
|
202
|
+
| { readonly success: true; readonly data: import("slate").Descendant[] }
|
|
203
|
+
| { readonly success: false; readonly error: Error; readonly fallback: import("slate").Descendant[] };
|
|
204
|
+
|
|
205
|
+
export type SlateToHtmlResult =
|
|
206
|
+
| { readonly success: true; readonly data: string }
|
|
207
|
+
| { readonly success: false; readonly error: Error; readonly fallback: string };
|
|
208
|
+
|
|
209
|
+
// Built-in Slate mark configurations with strict typing
|
|
210
|
+
export const SLATE_MARKS = {
|
|
158
211
|
bold: {
|
|
159
212
|
hotkey: "mod+b",
|
|
160
213
|
htmlTag: "strong",
|
|
@@ -200,18 +253,10 @@ export const SLATE_MARKS: Record<
|
|
|
200
253
|
icon: "𝐄𝐁",
|
|
201
254
|
renderHtml: (text: string) => `<span class="extrabold">${text}</span>`,
|
|
202
255
|
},
|
|
203
|
-
};
|
|
256
|
+
} as const;
|
|
204
257
|
|
|
205
|
-
// Built-in Slate block configurations
|
|
206
|
-
export const SLATE_BLOCKS
|
|
207
|
-
string,
|
|
208
|
-
{
|
|
209
|
-
htmlTag: string;
|
|
210
|
-
label: string;
|
|
211
|
-
icon: string;
|
|
212
|
-
renderHtml: (text: string, alignStyle: string) => string;
|
|
213
|
-
}
|
|
214
|
-
> = {
|
|
258
|
+
// Built-in Slate block configurations with strict typing
|
|
259
|
+
export const SLATE_BLOCKS = {
|
|
215
260
|
paragraph: {
|
|
216
261
|
htmlTag: "p",
|
|
217
262
|
label: "Paragraph",
|
|
@@ -267,23 +312,16 @@ export const SLATE_BLOCKS: Record<
|
|
|
267
312
|
renderHtml: (text: string, alignStyle: string) =>
|
|
268
313
|
`<h6${alignStyle}>${text}</h6>`,
|
|
269
314
|
},
|
|
270
|
-
};
|
|
315
|
+
} as const;
|
|
271
316
|
|
|
272
|
-
// Built-in alignment configurations
|
|
273
|
-
export const SLATE_ALIGNMENTS
|
|
274
|
-
|
|
275
|
-
{
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
> = {
|
|
281
|
-
left: { label: "Align Left", icon: "←", value: "left" },
|
|
282
|
-
center: { label: "Align Center", icon: "↔", value: "center" },
|
|
283
|
-
right: { label: "Align Right", icon: "→", value: "right" },
|
|
284
|
-
justify: { label: "Justify", icon: "≡", value: "justify" },
|
|
285
|
-
};
|
|
317
|
+
// Built-in alignment configurations with strict typing
|
|
318
|
+
export const SLATE_ALIGNMENTS = {
|
|
319
|
+
left: { label: "Align Left", icon: "←", value: "left" as const },
|
|
320
|
+
center: { label: "Align Center", icon: "↔", value: "center" as const },
|
|
321
|
+
right: { label: "Align Right", icon: "→", value: "right" as const },
|
|
322
|
+
justify: { label: "Justify", icon: "≡", value: "justify" as const },
|
|
323
|
+
} as const;
|
|
286
324
|
|
|
287
325
|
export type RichTextField = Field & {
|
|
288
|
-
source: string;
|
|
326
|
+
readonly source: string;
|
|
289
327
|
};
|