@monolith-forensics/monolith-ui 1.1.46 → 1.1.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/MonolithUIProvider/GlobalStyle.js +18 -0
  2. package/dist/MonolithUIProvider/MonolithUIProvider.d.ts +1 -1
  3. package/dist/RichTextEditor/Enums/Extensions.d.ts +15 -0
  4. package/dist/RichTextEditor/Enums/Extensions.js +16 -0
  5. package/dist/RichTextEditor/Enums/SlashCommands.d.ts +13 -0
  6. package/dist/RichTextEditor/Enums/SlashCommands.js +14 -0
  7. package/dist/RichTextEditor/Extensions/SlashCommandList.d.ts +9 -0
  8. package/dist/RichTextEditor/Extensions/SlashCommandList.js +138 -0
  9. package/dist/RichTextEditor/Extensions/getSlashCommand.d.ts +10 -0
  10. package/dist/RichTextEditor/Extensions/getSlashCommand.js +296 -0
  11. package/dist/RichTextEditor/Extensions/getTiptapExtensions.d.ts +11 -0
  12. package/dist/RichTextEditor/Extensions/getTiptapExtensions.js +178 -0
  13. package/dist/RichTextEditor/Plugins/UploadImagesPlugin.d.ts +16 -0
  14. package/dist/RichTextEditor/Plugins/UploadImagesPlugin.js +114 -0
  15. package/dist/RichTextEditor/RichTextEditor.d.ts +22 -0
  16. package/dist/RichTextEditor/RichTextEditor.js +302 -0
  17. package/dist/RichTextEditor/Toolbar/Control.d.ts +14 -0
  18. package/dist/RichTextEditor/Toolbar/Control.js +33 -0
  19. package/dist/RichTextEditor/Toolbar/Controls.d.ts +21 -0
  20. package/dist/RichTextEditor/Toolbar/Controls.js +120 -0
  21. package/dist/RichTextEditor/Toolbar/ControlsGroup.d.ts +8 -0
  22. package/dist/RichTextEditor/Toolbar/ControlsGroup.js +26 -0
  23. package/dist/RichTextEditor/Toolbar/Labels.d.ts +41 -0
  24. package/dist/RichTextEditor/Toolbar/Labels.js +46 -0
  25. package/dist/RichTextEditor/Toolbar/Toolbar.d.ts +7 -0
  26. package/dist/RichTextEditor/Toolbar/Toolbar.js +17 -0
  27. package/dist/RichTextEditor/Toolbar/index.d.ts +1 -0
  28. package/dist/RichTextEditor/Toolbar/index.js +1 -0
  29. package/dist/RichTextEditor/index.d.ts +3 -0
  30. package/dist/RichTextEditor/index.js +3 -0
  31. package/dist/Utilities/calculateFileHash.d.ts +8 -0
  32. package/dist/Utilities/calculateFileHash.js +38 -0
  33. package/dist/Utilities/readFileAsBuffer.d.ts +2 -0
  34. package/dist/Utilities/readFileAsBuffer.js +10 -0
  35. package/dist/index.d.ts +1 -0
  36. package/dist/index.js +1 -0
  37. package/package.json +19 -1
@@ -0,0 +1,178 @@
1
+ import TiptapImage from "@tiptap/extension-image";
2
+ import StarterKit from "@tiptap/starter-kit";
3
+ import HorizontalRule from "@tiptap/extension-horizontal-rule";
4
+ import Underline from "@tiptap/extension-underline";
5
+ import TextAlign from "@tiptap/extension-text-align";
6
+ import Table from "@tiptap/extension-table";
7
+ import TableCell from "@tiptap/extension-table-cell";
8
+ import TableHeader from "@tiptap/extension-table-header";
9
+ import TableRow from "@tiptap/extension-table-row";
10
+ import Placeholder from "@tiptap/extension-placeholder";
11
+ import { InputRule, Extension } from "@tiptap/core";
12
+ import Focus from "@tiptap/extension-focus";
13
+ import UploadImagesPlugin from "../Plugins/UploadImagesPlugin";
14
+ import getSlashCommand from "./getSlashCommand";
15
+ import Extensions from "../Enums/Extensions";
16
+ const CustomImage = TiptapImage.extend({
17
+ // Add data-uuid attribute to image
18
+ addAttributes() {
19
+ var _a;
20
+ return Object.assign(Object.assign({}, (_a = this.parent) === null || _a === void 0 ? void 0 : _a.call(this)), { "data-uuid": {
21
+ default: null,
22
+ } });
23
+ },
24
+ addProseMirrorPlugins() {
25
+ return [UploadImagesPlugin()];
26
+ },
27
+ });
28
+ const CustomStorage = Extension.create({
29
+ name: "customStorage",
30
+ addStorage() {
31
+ const data = {}; // Add index signature to the data object
32
+ return {
33
+ get: (key) => {
34
+ return data[key];
35
+ },
36
+ set: (key, value) => {
37
+ data[key] = value;
38
+ },
39
+ delete: (key) => {
40
+ delete data[key];
41
+ },
42
+ };
43
+ },
44
+ });
45
+ const getTipTapExtensions = ({ extensions = [], slashCommands = [], handleImageUpload, }) => {
46
+ return [
47
+ {
48
+ name: "starterKit",
49
+ category: "default",
50
+ extension: StarterKit.configure({
51
+ bulletList: {
52
+ HTMLAttributes: {
53
+ class: "",
54
+ },
55
+ },
56
+ orderedList: {
57
+ HTMLAttributes: {
58
+ class: "",
59
+ },
60
+ },
61
+ listItem: {
62
+ HTMLAttributes: {
63
+ class: "",
64
+ },
65
+ },
66
+ horizontalRule: false,
67
+ dropcursor: {
68
+ color: "#DBEAFE",
69
+ width: 4,
70
+ },
71
+ gapcursor: false,
72
+ }),
73
+ },
74
+ {
75
+ name: Extensions.Underline,
76
+ category: "default",
77
+ extension: Underline,
78
+ },
79
+ {
80
+ name: Extensions.TextAlign,
81
+ category: "default",
82
+ extension: TextAlign.configure({ types: ["heading", "paragraph"] }),
83
+ },
84
+ {
85
+ name: Extensions.Focus,
86
+ category: "default",
87
+ extension: Focus.configure({ className: "has-focus", mode: "all" }),
88
+ },
89
+ // patch to fix horizontal rule bug: https://github.com/ueberdosis/tiptap/pull/3859#issuecomment-1536799740
90
+ {
91
+ name: Extensions.HorizontalRule,
92
+ extension: HorizontalRule.extend({
93
+ addInputRules() {
94
+ return [
95
+ new InputRule({
96
+ find: /^(?:---|—-|___\s|\*\*\*\s)$/,
97
+ handler: ({ state, range }) => {
98
+ const attributes = {};
99
+ const { tr } = state;
100
+ const start = range.from;
101
+ let end = range.to;
102
+ tr.insert(start - 1, this.type.create(attributes)).delete(tr.mapping.map(start), tr.mapping.map(end));
103
+ },
104
+ }),
105
+ ];
106
+ },
107
+ }),
108
+ },
109
+ {
110
+ name: Extensions.Table,
111
+ extension: Table.configure({
112
+ resizable: true,
113
+ }),
114
+ },
115
+ {
116
+ name: Extensions.TableRow,
117
+ extension: TableRow,
118
+ },
119
+ {
120
+ name: Extensions.TableHeader,
121
+ extension: TableHeader,
122
+ },
123
+ {
124
+ name: Extensions.TableCell,
125
+ extension: TableCell,
126
+ },
127
+ {
128
+ name: Extensions.Image,
129
+ extension: CustomImage.configure({
130
+ allowBase64: true,
131
+ inline: true,
132
+ HTMLAttributes: {
133
+ class: "monolith-image",
134
+ },
135
+ }),
136
+ },
137
+ {
138
+ name: Extensions.Placeholder,
139
+ extension: Placeholder.configure({
140
+ placeholder: ({ node }) => {
141
+ // check if node type is tablcell
142
+ // if it is, return empty string
143
+ // table cells always contain a paragraph node, so no need to add placeholder to it
144
+ // other it shows two placeholders wihtin the cell
145
+ if (node.type.name === "tableCell") {
146
+ return "";
147
+ }
148
+ if (!extensions.includes(Extensions.SlashCommand)) {
149
+ return "Enter text...";
150
+ }
151
+ if (node.type.name === "heading") {
152
+ return `Heading ${node.attrs.level}`;
153
+ }
154
+ return "Press '/' for commands...";
155
+ },
156
+ includeChildren: true,
157
+ }),
158
+ },
159
+ {
160
+ name: Extensions.CustomStorage,
161
+ category: "default",
162
+ extension: CustomStorage,
163
+ },
164
+ {
165
+ name: Extensions.SlashCommand,
166
+ extension: getSlashCommand({
167
+ commands: slashCommands,
168
+ handleImageUpload,
169
+ }),
170
+ },
171
+ ]
172
+ .filter((ext) => {
173
+ return (extensions.includes(ext.name) ||
174
+ ext.category === "default");
175
+ })
176
+ .map((ext) => ext.extension);
177
+ };
178
+ export default getTipTapExtensions;
@@ -0,0 +1,16 @@
1
+ import { Plugin } from "@tiptap/pm/state";
2
+ import { DecorationSet, EditorView } from "@tiptap/pm/view";
3
+ interface HandleImageUploadProps {
4
+ file: File;
5
+ name: string;
6
+ id: string;
7
+ md5: string;
8
+ sha1: string;
9
+ sha256: string;
10
+ }
11
+ export interface HandleImageUpload {
12
+ (props: HandleImageUploadProps): Promise<string> | undefined;
13
+ }
14
+ export declare const startImageUpload: (file: File, view: EditorView, pos: number, handleImageUpload: HandleImageUpload | undefined) => void;
15
+ declare const UploadImagesPlugin: () => Plugin<DecorationSet>;
16
+ export default UploadImagesPlugin;
@@ -0,0 +1,114 @@
1
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
2
+ import { Decoration, DecorationSet } from "@tiptap/pm/view";
3
+ import { nanoid } from "nanoid";
4
+ import calculateFileHash from "../../Utilities/calculateFileHash";
5
+ const uploadKey = new PluginKey("upload-image");
6
+ function findPlaceholder(state, id) {
7
+ const decos = uploadKey.getState(state);
8
+ const found = decos.find(null, null, (spec) => spec.id === id);
9
+ return found.length ? found[0].from : null;
10
+ }
11
+ export const startImageUpload = (file, view, pos, handleImageUpload) => {
12
+ // check if the file is an image
13
+ if (!file.type.includes("image/")) {
14
+ alert("File type not supported.");
15
+ return;
16
+ // check if the file size is less than 20MB
17
+ }
18
+ else if (file.size / 1024 / 1024 > 20) {
19
+ alert("File size too big (max 20MB).");
20
+ return;
21
+ }
22
+ // A fresh object to act as the ID for this upload
23
+ const id = nanoid(25);
24
+ // Replace the selection with a placeholder
25
+ const tr = view.state.tr;
26
+ if (!tr.selection.empty)
27
+ tr.deleteSelection();
28
+ const reader = new FileReader();
29
+ reader.readAsDataURL(file);
30
+ reader.onload = () => {
31
+ tr.setMeta(uploadKey, {
32
+ add: {
33
+ id,
34
+ pos,
35
+ src: reader.result,
36
+ },
37
+ });
38
+ view.dispatch(tr);
39
+ };
40
+ calculateFileHash(file).then((hashes) => {
41
+ var _a;
42
+ const md5 = hashes.md5Hash;
43
+ const sha1 = hashes.sha1Hash;
44
+ const sha256 = hashes.sha256Hash;
45
+ (_a = handleImageUpload === null || handleImageUpload === void 0 ? void 0 : handleImageUpload({
46
+ file,
47
+ name: `${id}.png`,
48
+ id,
49
+ md5,
50
+ sha1,
51
+ sha256,
52
+ })) === null || _a === void 0 ? void 0 : _a.then((src) => {
53
+ if (!src)
54
+ return;
55
+ const { schema } = view.state;
56
+ let pos = findPlaceholder(view.state, id);
57
+ // If the content around the placeholder has been deleted, drop
58
+ // the image
59
+ if (pos == null)
60
+ return;
61
+ // Otherwise, insert it at the placeholder's position, and remove
62
+ // the placeholder
63
+ // When BLOB_READ_WRITE_TOKEN is not valid or unavailable, read
64
+ // the image locally
65
+ const imageSrc = typeof src === "object" ? reader.result : src;
66
+ const node = schema.nodes.image.create({
67
+ src: imageSrc,
68
+ alt: `${id}.png`,
69
+ "data-uuid": id,
70
+ title: `Filename: ${id}.png`,
71
+ });
72
+ const transaction = view.state.tr
73
+ .replaceWith(pos, pos, node)
74
+ .setMeta(uploadKey, { remove: { id } });
75
+ view.dispatch(transaction);
76
+ });
77
+ });
78
+ };
79
+ const UploadImagesPlugin = () => new Plugin({
80
+ key: uploadKey,
81
+ state: {
82
+ init() {
83
+ return DecorationSet.empty;
84
+ },
85
+ apply(tr, set) {
86
+ set = set.map(tr.mapping, tr.doc);
87
+ // See if the transaction adds or removes any placeholders
88
+ const action = tr.getMeta(this);
89
+ if (action && action.add) {
90
+ const { id, pos, src } = action.add;
91
+ const placeholder = document.createElement("div");
92
+ placeholder.setAttribute("class", "img-placeholder");
93
+ const image = document.createElement("img");
94
+ image.setAttribute("class", "monolith-image uploading");
95
+ image.src = src;
96
+ placeholder.appendChild(image);
97
+ const deco = Decoration.widget(pos + 1, placeholder, {
98
+ id,
99
+ });
100
+ set = set.add(tr.doc, [deco]);
101
+ }
102
+ else if (action && action.remove) {
103
+ set = set.remove(set.find(undefined, undefined, (spec) => spec.id === action.remove.id));
104
+ }
105
+ return set;
106
+ },
107
+ },
108
+ props: {
109
+ decorations(state) {
110
+ return this.getState(state);
111
+ },
112
+ },
113
+ });
114
+ export default UploadImagesPlugin;
@@ -0,0 +1,22 @@
1
+ import { Editor } from "@tiptap/react";
2
+ import { ExtensionType } from "./Extensions/getTiptapExtensions";
3
+ import { HandleImageUpload } from "./Plugins/UploadImagesPlugin";
4
+ interface RichTextEditorProps {
5
+ className?: string;
6
+ editorInstanceRef?: React.RefObject<Editor>;
7
+ extensions?: ExtensionType[];
8
+ slashCommands?: any[];
9
+ defaultValue?: string;
10
+ readOnly?: boolean;
11
+ height?: string;
12
+ font?: string;
13
+ showToolbar?: boolean;
14
+ saving?: boolean;
15
+ onChange?: (value: string) => void;
16
+ handleImageUpload?: HandleImageUpload;
17
+ style?: React.CSSProperties;
18
+ }
19
+ declare const RichTextEditor: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<Omit<RichTextEditorProps & import("react").RefAttributes<unknown>, "ref"> & {
20
+ ref?: ((instance: unknown) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<unknown> | null | undefined;
21
+ }, never>> & string & Omit<import("react").ForwardRefExoticComponent<RichTextEditorProps & import("react").RefAttributes<unknown>>, keyof import("react").Component<any, {}, any>>;
22
+ export default RichTextEditor;
@@ -0,0 +1,302 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef, useEffect } from "react";
3
+ import styled from "styled-components";
4
+ import { EditorContent, useEditor } from "@tiptap/react";
5
+ import Toolbar from "./Toolbar";
6
+ import getTipTapExtensions from "./Extensions/getTiptapExtensions";
7
+ import Extensions from "./Enums/Extensions";
8
+ const RichTextEditor = styled(forwardRef(({ className, editorInstanceRef, defaultValue = "", readOnly = false, font, showToolbar = true, saving = false, extensions = [], slashCommands = [], onChange, handleImageUpload, style, }, ref) => {
9
+ // check if image extension is included
10
+ if (extensions === null || extensions === void 0 ? void 0 : extensions.includes(Extensions.Image)) {
11
+ // Ensure that handleImageUpload is provided
12
+ if (!handleImageUpload) {
13
+ throw new Error("handleImageUpload is required when using the image extension.");
14
+ }
15
+ }
16
+ const editor = useEditor({
17
+ content: defaultValue,
18
+ editable: !readOnly,
19
+ extensions: getTipTapExtensions({
20
+ extensions,
21
+ slashCommands,
22
+ handleImageUpload,
23
+ }),
24
+ onUpdate: ({ editor }) => {
25
+ onChange === null || onChange === void 0 ? void 0 : onChange(editor.getHTML());
26
+ },
27
+ });
28
+ useEffect(() => {
29
+ const _ref = editorInstanceRef;
30
+ if (editorInstanceRef) {
31
+ _ref.current = editor;
32
+ }
33
+ }, [editor]);
34
+ return (_jsxs("div", { className: className, children: [showToolbar && _jsx(Toolbar, { editor: editor }), _jsx(EditorContent, { className: "editor-content", editor: editor, "data-font": font || null, style: style })] }));
35
+ })) `
36
+ position: relative;
37
+ display: flex;
38
+ flex-direction: column;
39
+ flex: 1 1 auto;
40
+ overflow-y: auto;
41
+ justify-content: flex-start;
42
+ align-items: center;
43
+
44
+ .editor-content {
45
+ height: ${({ height }) => height || "100%"};
46
+ width: 100%;
47
+ overflow-y: auto;
48
+ }
49
+
50
+ .editor-content[data-font="Times New Roman"] {
51
+ font-family: "Times New Roman", Times, serif;
52
+ }
53
+
54
+ .editor-content[data-font="Courier New"] {
55
+ font-family: "Courier New", Courier, monospace;
56
+ }
57
+
58
+ .editor-content[data-font="Arial"] {
59
+ font-family: Arial, Helvetica, sans-serif;
60
+ }
61
+
62
+ .editor-content[data-font="Segoe UI"] {
63
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
64
+ }
65
+
66
+ .editor-content[data-font="Verdana"] {
67
+ font-family: Verdana, Geneva, Tahoma, sans-serif;
68
+ }
69
+
70
+ .editor-content[data-font="Roboto"] {
71
+ font-family: Roboto, sans-serif;
72
+ }
73
+
74
+ .ProseMirror {
75
+ font-weight: 400;
76
+ outline: none;
77
+ height: 100%;
78
+ padding: 1rem 4rem;
79
+ border-radius: 8px;
80
+ border: 1px solid transparent;
81
+ white-space: break-spaces;
82
+ word-break: break-word;
83
+ text-rendering: optimizeLegibility;
84
+
85
+ table {
86
+ border-collapse: collapse;
87
+ width: 100%;
88
+
89
+ th,
90
+ td {
91
+ border: 1px solid ${({ theme }) => theme.palette.divider};
92
+ padding: 0.5rem;
93
+ min-width: 100px;
94
+ }
95
+
96
+ // for table header
97
+ th {
98
+ border: 1px solid ${({ theme }) => theme.palette.divider};
99
+ padding: 0.5rem;
100
+ min-width: 100px;
101
+ background-color: ${({ theme }) => theme.palette.action.hover};
102
+ font-weight: 500;
103
+ }
104
+ }
105
+
106
+ h1 {
107
+ font-size: 1.5rem;
108
+ line-height: 2rem;
109
+ margin: 0;
110
+ }
111
+ h2 {
112
+ font-size: 1.25rem;
113
+ line-height: 1.75rem;
114
+ margin: 0;
115
+ }
116
+ h3 {
117
+ font-size: 1.125rem;
118
+ line-height: 1.75rem;
119
+ margin: 0;
120
+ }
121
+ h4 {
122
+ font-size: 1rem;
123
+ line-height: 1.5rem;
124
+ margin: 0;
125
+ }
126
+ p {
127
+ margin: 0;
128
+ font-size: 0.8rem;
129
+ line-height: 1.5rem;
130
+ }
131
+ ul {
132
+ margin: 0;
133
+ }
134
+ ol {
135
+ margin: 0;
136
+ }
137
+ .editor-link {
138
+ color: ${({ theme }) => theme.palette.primary.main};
139
+ }
140
+ .editor-link:hover {
141
+ color: ${({ theme }) => theme.palette.text.primary};
142
+ text-decoration: underline;
143
+ cursor: pointer;
144
+ // Set title attribute
145
+ title: "Click to open link";
146
+ }
147
+ img {
148
+ max-width: 100%;
149
+ max-height: 25rem;
150
+ border: 1px solid ${({ theme }) => theme.palette.divider};
151
+ }
152
+ img.has-focus {
153
+ border: 1px solid ${({ theme }) => theme.palette.primary.main};
154
+ }
155
+ }
156
+
157
+ .ProseMirror .is-editor-empty:first-child::before {
158
+ content: attr(data-placeholder);
159
+ float: left;
160
+ color: #888;
161
+ pointer-events: none;
162
+ height: 0;
163
+ }
164
+ .ProseMirror .is-empty::before {
165
+ content: attr(data-placeholder);
166
+ float: left;
167
+ color: #888;
168
+ pointer-events: none;
169
+ height: 0;
170
+ }
171
+
172
+ .ProseMirror .monolith-image.uploading {
173
+ opacity: 0.25;
174
+ }
175
+
176
+ .ProseMirror .img-placeholder {
177
+ position: relative;
178
+ width: fit-content;
179
+
180
+ &:before {
181
+ content: "";
182
+ box-sizing: border-box;
183
+ position: absolute;
184
+ top: calc(50% - 18px);
185
+ left: calc(50% - 18px);
186
+ width: 36px;
187
+ height: 36px;
188
+ border-radius: 50%;
189
+ border: 3px solid ${({ theme }) => theme.palette.primary.main};
190
+ border-top-color: ${({ theme }) => theme.palette.divider};
191
+ animation: spinning 0.6s linear infinite;
192
+ }
193
+
194
+ @keyframes spinning {
195
+ to {
196
+ transform: rotate(360deg);
197
+ }
198
+ }
199
+ }
200
+
201
+ .floating-menu {
202
+ display: flex;
203
+ background-color: #0d0d0d10;
204
+ padding: 0.2rem;
205
+ border-radius: 0.5rem;
206
+
207
+ button {
208
+ border: none;
209
+ outline: none;
210
+ background: none;
211
+ font-size: 0.5rem;
212
+ font-weight: 500;
213
+ padding: 0 0.2rem;
214
+ color: ${({ theme }) => theme.palette.text.primary};
215
+
216
+ &:hover,
217
+ &:focus,
218
+ &.is-active {
219
+ opacity: 1;
220
+ color: ${({ theme }) => theme.palette.primary.main};
221
+ }
222
+ }
223
+ }
224
+
225
+ ul[data-type="taskList"] {
226
+ list-style: none;
227
+ padding: 0;
228
+
229
+ li {
230
+ display: flex;
231
+ align-items: center;
232
+ margin: 0.25rem 0;
233
+
234
+ > label {
235
+ flex: 0 0 auto;
236
+ margin-right: 0.5rem;
237
+ user-select: none;
238
+ }
239
+
240
+ > div {
241
+ flex: 1 1 auto;
242
+ }
243
+ }
244
+
245
+ input[type="checkbox"] {
246
+ cursor: pointer;
247
+ margin: 0;
248
+ -webkit-appearance: none;
249
+ appearance: none;
250
+ border: 2px solid ${({ theme }) => theme.palette.primary.main};
251
+ border-radius: 0.125rem;
252
+ background-color: ${({ theme }) => theme.palette.background.default};
253
+ width: 1.25rem;
254
+ height: 1.25rem;
255
+ display: grid;
256
+ place-content: center;
257
+
258
+ &:hover {
259
+ border-color: ${({ theme }) => theme.palette.primary.main};
260
+ }
261
+
262
+ &:active {
263
+ background-color: ${({ theme }) => theme.palette.divider};
264
+ }
265
+
266
+ &::before {
267
+ content: "";
268
+ width: 0.75em;
269
+ height: 0.75em;
270
+ transform: scale(0);
271
+ transition: 120ms transform ease-in-out;
272
+ box-shadow: inset 1em 1em;
273
+ transform-origin: center;
274
+ clip-path: polygon(14% 44%, 0 65%, 50% 100%, 100% 16%, 80% 0%, 43% 62%);
275
+ color: ${({ theme }) => theme.palette.text.primary};
276
+ }
277
+
278
+ &:checked::before {
279
+ transform: scale(1);
280
+ }
281
+ }
282
+ }
283
+
284
+ ul[data-type="taskList"] li[data-checked="true"] > div > p {
285
+ color: ${({ theme }) => theme.palette.text.secondary};
286
+ opacity: 0.5;
287
+ text-decoration: line-through;
288
+ text-decoration-thickness: 1px;
289
+ }
290
+
291
+ .ProseMirror .note-tag {
292
+ border: 1px solid ${({ theme }) => theme.palette.divider};
293
+ border-radius: 0.25rem;
294
+ padding: 0.125rem 0.25rem;
295
+ font-size: 0.75rem;
296
+ line-height: 1rem;
297
+ color: ${({ theme }) => theme.palette.text.secondary};
298
+ font-weight: 500;
299
+ margin: 0 0.125rem;
300
+ }
301
+ `;
302
+ export default RichTextEditor;
@@ -0,0 +1,14 @@
1
+ import { Editor } from "@tiptap/react";
2
+ interface ControlProps {
3
+ className?: string;
4
+ editor: Editor | null;
5
+ isActive?: any;
6
+ operation: {
7
+ name: string;
8
+ attributes?: any;
9
+ };
10
+ label: string;
11
+ icon: any;
12
+ }
13
+ declare const Control: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<ControlProps, never>> & string & Omit<({ className, editor, isActive, operation, label, icon: Icon, }: ControlProps) => import("react/jsx-runtime").JSX.Element, keyof import("react").Component<any, {}, any>>;
14
+ export default Control;
@@ -0,0 +1,33 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import styled from "styled-components";
3
+ import Labels from "./Labels";
4
+ const Control = styled(({ className, editor, isActive, operation, label, icon: Icon, }) => {
5
+ var _a;
6
+ const _label = Labels[label];
7
+ const active = (isActive === null || isActive === void 0 ? void 0 : isActive.name)
8
+ ? (_a = editor === null || editor === void 0 ? void 0 : editor.isActive) === null || _a === void 0 ? void 0 : _a.call(editor, isActive.name, isActive.attributes)
9
+ : false;
10
+ return (_jsx("button", { className: className + (active ? " active" : ""), "aria-label": _label, "data-active": active, title: _label, onClick: () => {
11
+ const focus = editor === null || editor === void 0 ? void 0 : editor.chain().focus();
12
+ focus[operation.name](operation.attributes).run();
13
+ }, children: _jsx(Icon, { size: "16px" }) }));
14
+ }) `
15
+ display: flex;
16
+ justify-content: center;
17
+ align-items: center;
18
+ width: 1.5rem;
19
+ height: 1.5rem;
20
+ padding: 0px;
21
+ background-color: transparent;
22
+ cursor: pointer;
23
+ color: ${({ theme }) => theme.palette.text.primary};
24
+ &:hover {
25
+ background-color: ${({ theme }) => theme.palette.action.hover};
26
+ }
27
+ &.active {
28
+ background-color: ${({ theme }) => theme.palette.action.hover};
29
+ color: ${({ theme }) => theme.palette.primary.main};
30
+ }
31
+ `;
32
+ Control.displayName = "Control";
33
+ export default Control;