Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62d2938a93 |
@@ -0,0 +1,27 @@
|
||||
import { Node } from "@tiptap/pm/model";
|
||||
import { Decoration, DecorationSet } from "@tiptap/pm/view";
|
||||
|
||||
export const findAllColors = (doc: Node): DecorationSet => {
|
||||
const hexColor = /(#[0-9a-f]{3,6})\b/gi;
|
||||
const decorations: Decoration[] = [];
|
||||
|
||||
doc.descendants((node, position) => {
|
||||
if (!node.text) {
|
||||
return;
|
||||
}
|
||||
|
||||
Array.from(node.text.matchAll(hexColor)).forEach((match) => {
|
||||
const color = match[0];
|
||||
const index = match.index || 0;
|
||||
const from = position + index;
|
||||
const to = from + color.length;
|
||||
const decoration = Decoration.inline(from, to, {
|
||||
class: "editor-color-swatch",
|
||||
style: `--color: ${color}`,
|
||||
});
|
||||
decorations.push(decoration);
|
||||
});
|
||||
});
|
||||
|
||||
return DecorationSet.create(doc, decorations);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
export * from "./root";
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Extension } from "@tiptap/core";
|
||||
import { Plugin } from "@tiptap/pm/state";
|
||||
// helpers
|
||||
import { findAllColors } from "./helpers";
|
||||
|
||||
export const ColorHighlighter = Extension.create({
|
||||
name: "colorHighlighter",
|
||||
|
||||
addProseMirrorPlugins() {
|
||||
return [
|
||||
new Plugin({
|
||||
state: {
|
||||
init(_, { doc }) {
|
||||
return findAllColors(doc);
|
||||
},
|
||||
apply(transaction, oldState) {
|
||||
return transaction.docChanged ? findAllColors(transaction.doc) : oldState;
|
||||
},
|
||||
},
|
||||
props: {
|
||||
decorations(state) {
|
||||
return this.getState(state);
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
},
|
||||
});
|
||||
@@ -3,11 +3,12 @@ import TaskList from "@tiptap/extension-task-list";
|
||||
import TextStyle from "@tiptap/extension-text-style";
|
||||
import TiptapUnderline from "@tiptap/extension-underline";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
// extensions
|
||||
// helpers
|
||||
import { isValidHttpUrl } from "@/helpers/common";
|
||||
// extensions
|
||||
import { CustomCodeBlockExtensionWithoutProps } from "./code/without-props";
|
||||
import { CustomCodeInlineExtension } from "./code-inline";
|
||||
import { ColorHighlighter } from "./color-highlighter";
|
||||
import { CustomLinkExtension } from "./custom-link";
|
||||
import { CustomHorizontalRule } from "./horizontal-rule";
|
||||
import { ImageExtensionWithoutProps } from "./image";
|
||||
@@ -81,6 +82,7 @@ export const CoreEditorExtensionsWithoutProps = [
|
||||
TableCell,
|
||||
TableRow,
|
||||
CustomMentionWithoutProps(),
|
||||
ColorHighlighter,
|
||||
];
|
||||
|
||||
export const DocumentEditorExtensionsWithoutProps = [IssueWidgetWithoutProps()];
|
||||
|
||||
@@ -8,6 +8,7 @@ import StarterKit from "@tiptap/starter-kit";
|
||||
import { Markdown } from "tiptap-markdown";
|
||||
// extensions
|
||||
import {
|
||||
ColorHighlighter,
|
||||
CustomCodeBlockExtension,
|
||||
CustomCodeInlineExtension,
|
||||
CustomCodeMarkPlugin,
|
||||
@@ -159,4 +160,5 @@ export const CoreEditorExtensions = ({
|
||||
includeChildren: true,
|
||||
}),
|
||||
CharacterCount,
|
||||
ColorHighlighter,
|
||||
];
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from "./code";
|
||||
export * from "./code-inline";
|
||||
export * from "./color-highlighter";
|
||||
export * from "./custom-link";
|
||||
export * from "./custom-list-keymap";
|
||||
export * from "./image";
|
||||
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
TableRow,
|
||||
Table,
|
||||
CustomMention,
|
||||
ColorHighlighter,
|
||||
} from "@/extensions";
|
||||
// helpers
|
||||
import { isValidHttpUrl } from "@/helpers/common";
|
||||
@@ -106,4 +107,5 @@ export const CoreReadOnlyEditorExtensions = (mentionConfig: {
|
||||
readonly: true,
|
||||
}),
|
||||
CharacterCount,
|
||||
ColorHighlighter,
|
||||
];
|
||||
|
||||
@@ -458,3 +458,24 @@ ul[data-type="taskList"] ul[data-type="taskList"] {
|
||||
margin-top: 0;
|
||||
}
|
||||
/* end tailwind typography */
|
||||
|
||||
/* color swatch */
|
||||
.editor-color-swatch {
|
||||
white-space: nowrap;
|
||||
|
||||
&::before {
|
||||
background-color: var(--color);
|
||||
border: 1px solid rgba(128, 128, 128, 0.3);
|
||||
border-radius: 4px;
|
||||
content: "";
|
||||
display: inline-block;
|
||||
height: var(--font-size-regular);
|
||||
width: var(--font-size-regular);
|
||||
aspect-ratio: 1 / 1;
|
||||
margin-bottom: 0.15em;
|
||||
margin-right: 0.1em;
|
||||
vertical-align: middle;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
/* end color swatch */
|
||||
|
||||
Reference in New Issue
Block a user