TipTap - Applying styles to <a> tags

I’ve had some time to spend with U16 TipTap and got hideously stuck on applying styles to links. If i just attempt to apply a class it applies to the containing block element instead.

A tags aren’t in the list of supported tags, is there any way of editing these?

Or has anyone found a workable workaround?

Well it nearly broke me but I found a workaround in the end

// App_Plugins/LinkStylesDropdown/umbraco-package.json

{
  "name": "LinksStyles",
  "version": "1.0.0",
  "extensions": [
    {
      "type": "bundle",
      "alias": "RTELinksDropdown",
      "name": "RTELinksDropdown",
      "js": "/App_Plugins/LinkStylesDropdown/link-styles-dropdown.js"
    }
  ]
}
// App_Plugins/LinkStylesDropdown/link-styles-dropdown.js

export const manifests = [
    {
        type: "tiptapToolbarExtension",
        kind: "styleMenu",
        alias: "ACME.Tiptap.Toolbar.LinkStylesDD",
        name: "Link Styles Dropdown",
        api: () => import("./LinkStylesDropdown.api.js"),
        meta: {
            alias: "linkStyles",
            icon: "icon-link",
            label: "Link Styles",
            items: [
                { label: "Button Primary", value: "btn btn-primary" },
                { label: "Button Secondary", value: "btn btn-secondary" },
                { label: "External Link", value: "link-external" }
            ]
        }
    }
]

// App_Plugins/LinkStylesDropdown/LinkStyleDropdown.api

import { UmbTiptapToolbarElementApiBase } from '@umbraco-cms/backoffice/tiptap';


export default class LinkStyleMenuApi extends UmbTiptapToolbarElementApiBase {
	
	isActive(editor, item) {
		if (!editor || !item?.value) return false;
		const attrs = editor?.getAttributes('umbLink');
		const className = item.value;
		let classMatch = false;

		if (attrs.class == " " && className == " ") {
			classMatch = true;
		} else {
			classMatch = !className ? true : attrs.class?.includes(className) === true;
		}
		

		return classMatch;
	}

	execute(editor, item) {
		if (!editor || !item?.value) return;
		const className = item.value;

		
		editor?.chain().focus().toggleClassName(className, 'umbLink').run();
		
	}
}






That gives me a dropdown that will apply the classes to any existing umbraco link (e.g. one inserted with the link toolbar button).

Great that you were able to find a solution!

Can I ask if you ever considered adding the buttons as inline blocks?
In a block, you can have a settings model that allows your users to select styling, behavior, and such, and you control the output through a partial view on the frontend. You can add whatever CSS classes you’d like without having to migrate content if, say, your classes change in the future.

Ahh, I hadn’t considered inline blocks, I had assumed (wrongly by the sounds of it) that blocks were block level by their nature! Looking at these was my next job either way :slight_smile: thanks!

The eternal prerogative of a developer is to decide between applying classes directly or more. I totally get why you’d choose to add the classes, even if you knew blocks could be inline. The good thing is that it is now easier for your users to apply the classes to existing links, whereas they would have had to recreate them if you went down the blocks route.

Hi @Rich

I’m hoping your workaround will also work for me, but I can’t seem to get it to work.

I’ve added the files, and I’ve added the button to TipTap, but nothing happens.

I get a button with the text “Link Styles” and the down-arrow. But it doesn’t pop open. I’m using Umbraco 17 at the moment. Could that be the problem?

I’ve added some log lines in the LinkStyleDropdown.api.js file. It seems that itemis undefined, no matter what I select in the content of the RTE. But I don’t know if that has anything to do with not opening the dropdown.

Hi, yes, this was in 16 - I’ve not had a chance to test out 17 yet - but will do in the coming weeks I expect.. I just checked and it’s still OK in 16 for me. If i get a chance to check it out sooner i’ll post back!

Thanks.

I guess something is changed. Your isActive(editor, item) has 2 parameters. But the documentation has only mentions the editor parameter.

But maybe I’m mistaken. I’ve never created any plugins :slight_smile:

edit: @Rich I fixed in my case.

In your link-styles-dropdown.js code in the OP, you have the items property within the metaproperty. I moved it outside of the metaproperty, and now it works.