fix: button detection with text alignment

Added data-button attribute selector to TipTap button parseHTML.
This ensures buttons are properly detected when text alignment is
applied, as alignment may affect CSS class detection.

Priority order:
1. a[data-button] - most reliable
2. a.button
3. a.button-outline
This commit is contained in:
Dwindi Ramadhana
2026-01-01 23:34:41 +07:00
parent 47f6370ce0
commit 2ce7c0b263

View File

@@ -37,6 +37,9 @@ export const ButtonExtension = Node.create<ButtonOptions>({
parseHTML() { parseHTML() {
return [ return [
{
tag: 'a[data-button]',
},
{ {
tag: 'a.button', tag: 'a.button',
}, },
@@ -49,29 +52,29 @@ export const ButtonExtension = Node.create<ButtonOptions>({
renderHTML({ HTMLAttributes }) { renderHTML({ HTMLAttributes }) {
const { text, href, style } = HTMLAttributes; const { text, href, style } = HTMLAttributes;
const className = style === 'outline' ? 'button-outline' : 'button'; const className = style === 'outline' ? 'button-outline' : 'button';
const buttonStyle: Record<string, string> = style === 'solid' const buttonStyle: Record<string, string> = style === 'solid'
? { ? {
display: 'inline-block', display: 'inline-block',
background: '#7f54b3', background: '#7f54b3',
color: '#fff', color: '#fff',
padding: '14px 28px', padding: '14px 28px',
borderRadius: '6px', borderRadius: '6px',
textDecoration: 'none', textDecoration: 'none',
fontWeight: '600', fontWeight: '600',
cursor: 'pointer', cursor: 'pointer',
} }
: { : {
display: 'inline-block', display: 'inline-block',
background: 'transparent', background: 'transparent',
color: '#7f54b3', color: '#7f54b3',
padding: '12px 26px', padding: '12px 26px',
border: '2px solid #7f54b3', border: '2px solid #7f54b3',
borderRadius: '6px', borderRadius: '6px',
textDecoration: 'none', textDecoration: 'none',
fontWeight: '600', fontWeight: '600',
cursor: 'pointer', cursor: 'pointer',
}; };
return [ return [
'a', 'a',
@@ -94,12 +97,12 @@ export const ButtonExtension = Node.create<ButtonOptions>({
return { return {
setButton: setButton:
(options) => (options) =>
({ commands }) => { ({ commands }) => {
return commands.insertContent({ return commands.insertContent({
type: this.name, type: this.name,
attrs: options, attrs: options,
}); });
}, },
}; };
}, },
}); });