Skip to content

Commit 9abcb7b

Browse files
committed
fix: Resolve parameter errors and change loss caused by code conflicts after upgrading Tiptap version
1 parent ca19206 commit 9abcb7b

File tree

4 files changed

+75
-59
lines changed

4 files changed

+75
-59
lines changed

src/extensions/Color/Color.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ export interface ColorOptions extends TiptapColorOptions, GeneralOptions<ColorOp
1515
defaultColor?: string
1616
}
1717

18+
export interface ColorStorage {
19+
currentColor?: string
20+
}
21+
22+
declare module '@tiptap/core' {
23+
interface Storage {
24+
color: ColorStorage
25+
}
26+
}
27+
1828
export const Color = /* @__PURE__ */ TiptapColor.extend<ColorOptions>({
1929
addStorage() {
2030
return {
@@ -37,12 +47,12 @@ export const Color = /* @__PURE__ */ TiptapColor.extend<ColorOptions>({
3747
action: (color?: unknown) => {
3848
if (typeof color === 'string') {
3949
// Update the stored current color
40-
extension.storage.currentColor = color;
50+
editor.storage.color.currentColor = color;
4151
editor.chain().focus().setColor(color).run();
4252
}
4353
if (color === undefined) {
4454
// Clear the color and set currentColor to undefined
45-
extension.storage.currentColor = undefined;
55+
editor.storage.color.currentColor = undefined;
4656
editor.chain().focus().unsetColor().run();
4757
}
4858
},
@@ -71,25 +81,24 @@ export const Color = /* @__PURE__ */ TiptapColor.extend<ColorOptions>({
7181
// Use the stored current color
7282
const colorToUse = this.storage.currentColor || this.options.defaultColor;
7383

74-
// If currentColor is undefined (indicating No Fill/default), do not perform color operation
84+
// If colorToUse is undefined, remove any existing color
7585
if (!colorToUse) {
86+
const { color: currentTextColor } = this.editor.getAttributes('textStyle');
87+
if (currentTextColor) {
88+
return this.editor.chain().focus().unsetColor().run();
89+
}
7690
return false;
7791
}
7892

79-
// Check if there is already a text color
80-
const { color: currentTextColor } = this.editor.getAttributes('textStyle');
81-
82-
if (currentTextColor) {
83-
// If the current text color is the same as colorToUse, remove it
84-
if (currentTextColor === colorToUse) {
85-
return this.editor.chain().focus().unsetColor().run();
86-
}
93+
// Check if the ENTIRE selection has the exact same text color
94+
const isExactColorActive = this.editor.isActive('textStyle', { color: colorToUse });
8795

88-
// Otherwise, replace with the new color
89-
return this.editor.chain().focus().setColor(colorToUse).run();
96+
if (isExactColorActive) {
97+
// If the entire selection has this exact color, remove it
98+
return this.editor.chain().focus().unsetColor().run();
9099
}
91100

92-
// If there is no color, add it
101+
// Otherwise (no color, different color, or mixed state), apply the color
93102
return this.editor.chain().focus().setColor(colorToUse).run();
94103
},
95104
};

src/extensions/Color/components/ColorActionButton.tsx

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,19 @@ function IconC({ fill }: IconCProps) {
7070
}
7171

7272
function ColorActionButton(props: ColorActionButtonProps) {
73-
// Read the shared current color from extension.storage
73+
// Read the shared current color from editor.storage
7474
const getStoredColor = () => {
75-
return props.extension?.storage?.currentColor || props?.defaultColor;
75+
return props.editor?.storage?.color?.currentColor || props?.defaultColor;
7676
};
7777

7878
const [selectedColor, setSelectedColor] = useState<string | undefined>(getStoredColor());
7979

8080
// Listen for editor updates and sync the color from storage
8181
useEffect(() => {
82-
if (!props.editor || !props.extension) return;
82+
if (!props.editor) return;
8383

8484
const updateColor = () => {
85-
const storedColor = props.extension.storage.currentColor;
85+
const storedColor = props.editor?.storage?.color?.currentColor;
8686
if (storedColor !== selectedColor) {
8787
setSelectedColor(storedColor);
8888
}
@@ -91,25 +91,25 @@ function ColorActionButton(props: ColorActionButtonProps) {
9191
props.editor.on('transaction', updateColor);
9292

9393
return () => {
94-
9594
props.editor.off('transaction', updateColor);
9695
};
97-
}, [props.editor, props.extension, selectedColor]);
96+
}, [props.editor, selectedColor]);
9897

9998
function onChange(color: string | undefined) {
10099
// Immediately update the color in storage (including undefined)
101-
if (props.extension) {
102-
props.extension.storage.currentColor = color;
100+
if (props.editor?.storage?.color) {
101+
props.editor.storage.color.currentColor = color;
103102
}
104103
props.action?.(color);
105104
}
106105

107106
function toggleColor() {
108107
// Use the current color from storage
109-
const colorToUse = props.extension?.storage?.currentColor || selectedColor;
108+
const colorToUse = props.editor?.storage?.color?.currentColor || selectedColor;
110109

111-
// If the color is undefined (No Fill/default), do not perform any operation
110+
// If the color is undefined (No Fill/default), call action with undefined to clear color
112111
if (!colorToUse) {
112+
props.action?.(undefined);
113113
return;
114114
}
115115

@@ -120,11 +120,11 @@ function ColorActionButton(props: ColorActionButtonProps) {
120120
(color: string | undefined) => {
121121
setSelectedColor(color);
122122
// Update storage (including undefined)
123-
if (props.extension) {
124-
props.extension.storage.currentColor = color;
123+
if (props.editor?.storage?.color) {
124+
props.editor.storage.color.currentColor = color;
125125
}
126126
},
127-
[props.extension],
127+
[props.editor],
128128
);
129129

130130
return (

src/extensions/Highlight/Highlight.ts

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,16 @@ export interface HighlightOptions extends TiptapHighlightOptions, GeneralOptions
1313
defaultColor?: string
1414
}
1515

16+
export interface HighlightStorage {
17+
currentColor?: string
18+
}
19+
20+
declare module '@tiptap/core' {
21+
interface Storage {
22+
highlight: HighlightStorage
23+
}
24+
}
25+
1626
export const Highlight = /* @__PURE__ */ TiptapHighlight.extend<HighlightOptions>({
1727
addStorage() {
1828
return {
@@ -32,12 +42,12 @@ export const Highlight = /* @__PURE__ */ TiptapHighlight.extend<HighlightOptions
3242
action: (color?: unknown) => {
3343
if (typeof color === 'string') {
3444
// Update the stored current color
35-
extension.storage.currentColor = color;
45+
editor.storage.highlight.currentColor = color;
3646
editor.chain().focus().setHighlight({ color }).run();
3747
}
3848
if (color === undefined) {
3949
// Clear the highlight and set currentColor to undefined
40-
extension.storage.currentColor = undefined;
50+
editor.storage.highlight.currentColor = undefined;
4151
editor.chain().focus().unsetHighlight().run();
4252
}
4353
},
@@ -60,26 +70,24 @@ export const Highlight = /* @__PURE__ */ TiptapHighlight.extend<HighlightOptions
6070
// Use the stored current color
6171
const colorToUse = this.storage.currentColor || this.options.defaultColor;
6272

63-
// If currentColor is undefined (indicating No Fill), do not perform highlight
73+
// If colorToUse is undefined, remove any existing highlight
6474
if (!colorToUse) {
65-
return false;
66-
}
67-
68-
// Check if there is already a highlight
69-
if (this.editor.isActive('highlight')) {
70-
// Get the current highlight color
7175
const { color: currentHighlightColor } = this.editor.getAttributes('highlight');
72-
73-
// If the current highlight color is the same as colorToUse, remove it
74-
if (currentHighlightColor === colorToUse) {
76+
if (currentHighlightColor) {
7577
return this.editor.chain().focus().unsetHighlight().run();
7678
}
79+
return false;
80+
}
81+
82+
// Check if the ENTIRE selection has the exact same highlight color
83+
const isExactColorActive = this.editor.isActive('highlight', { color: colorToUse });
7784

78-
// Otherwise, replace with the new color
79-
return this.editor.chain().focus().setHighlight({ color: colorToUse }).run();
85+
if (isExactColorActive) {
86+
// If the entire selection has this exact color, remove it
87+
return this.editor.chain().focus().unsetHighlight().run();
8088
}
8189

82-
// If there is no highlight, add it
90+
// Otherwise (no highlight, different color, or mixed state), apply the color
8391
return this.editor.chain().focus().setHighlight({ color: colorToUse }).run();
8492
},
8593
};

src/extensions/Highlight/components/HighlightActionButton.tsx

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,19 +70,19 @@ function IconC({ fill }: any) {
7070
}
7171

7272
function HighlightActionButton(props: IPropsHighlightActionButton) {
73-
// Read the shared current color from extension.storage.
73+
// Read the shared current color from editor.storage
7474
const getStoredColor = () => {
75-
return props.extension?.storage?.currentColor || props?.defaultColor;
75+
return props.editor?.storage?.highlight?.currentColor || props?.defaultColor;
7676
};
7777

7878
const [selectedColor, setSelectedColor] = useState<string | undefined>(getStoredColor());
7979

8080
// Listen for editor updates and synchronize the displayed color with the one in storage.
8181
useEffect(() => {
82-
if (!props.editor || !props.extension) return;
82+
if (!props.editor) return;
8383

8484
const updateColor = () => {
85-
const storedColor = props.extension.storage.currentColor;
85+
const storedColor = props.editor?.storage?.highlight?.currentColor;
8686
if (storedColor !== selectedColor) {
8787
setSelectedColor(storedColor);
8888
}
@@ -95,37 +95,36 @@ function HighlightActionButton(props: IPropsHighlightActionButton) {
9595
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
9696
props.editor.off('transaction', updateColor);
9797
};
98-
}, [props.editor, props.extension, selectedColor]);
98+
}, [props.editor, selectedColor]);
9999

100100
function onChange(color: string | undefined) {
101101
// Immediately update the color in storage (including undefined)
102-
if (props.extension) {
103-
props.extension.storage.currentColor = color;
102+
if (props.editor?.storage?.highlight) {
103+
props.editor.storage.highlight.currentColor = color;
104104
}
105105
props.action?.(color);
106106
}
107107

108108
function toggleColor() {
109109
// Use the stored current color
110-
const colorToUse = props.extension?.storage?.currentColor || selectedColor;
111-
112-
// If the color is undefined (No Fill), do not perform any action
110+
const colorToUse = props.editor?.storage?.highlight?.currentColor || selectedColor;
111+
112+
// If the color is undefined (No Fill), call action with undefined to clear highlight
113113
if (!colorToUse) {
114+
props.action?.(undefined);
114115
return;
115116
}
116-
117-
props.action?.(colorToUse);
118-
}
119117

120-
const setSelectedColorDebounce = useCallback(
118+
props.action?.(colorToUse);
119+
} const setSelectedColorDebounce = useCallback(
121120
(color: string | undefined) => {
122121
setSelectedColor(color);
123122
// Immediately update the color in storage (including undefined)
124-
if (props.extension) {
125-
props.extension.storage.currentColor = color;
123+
if (props.editor?.storage?.highlight) {
124+
props.editor.storage.highlight.currentColor = color;
126125
}
127126
},
128-
[props.extension],
127+
[props.editor],
129128
);
130129

131130
return (

0 commit comments

Comments
 (0)