Skip to content

Instantly share code, notes, and snippets.

@gregveres
Created May 3, 2022 22:34
Show Gist options
  • Save gregveres/64ec1d8a733feb735b7dd4c46331abae to your computer and use it in GitHub Desktop.
Save gregveres/64ec1d8a733feb735b7dd4c46331abae to your computer and use it in GitHub Desktop.
font-size for tiptap 2
import { Extension } from "@tiptap/core";
import "@tiptap/extension-text-style";
export type FontSizeOptions = {
types: string[];
};
declare module "@tiptap/core" {
interface Commands<ReturnType> {
fontSize: {
/**
* Set the font size
*/
setFontSize: (fontSize: string) => ReturnType;
/**
* Unset the font size
*/
unsetFontSize: () => ReturnType;
};
}
}
export const FontSize = Extension.create<FontSizeOptions>({
name: "fontSize",
addOptions() {
return {
types: ["textStyle"],
};
},
addGlobalAttributes() {
return [
{
types: this.options.types,
attributes: {
fontSize: {
default: null,
parseHTML: (element) =>
element.style.fontSize.replace(/['"]+/g, ""),
renderHTML: (attributes) => {
if (!attributes.fontSize) {
return {};
}
return {
style: `font-size: ${attributes.fontSize}`,
};
},
},
},
},
];
},
addCommands() {
return {
setFontSize:
(fontSize) =>
({ chain }) => {
return chain().setMark("textStyle", { fontSize }).run();
},
unsetFontSize:
() =>
({ chain }) => {
return chain()
.setMark("textStyle", { fontSize: null })
.removeEmptyTextStyle()
.run();
},
};
},
});
@aberkayk
Copy link

is there any example of this ?

@gregveres
Copy link
Author

is there any example of this ?

Here is how I use it in my editor. I am still using Vuetify 2.x, but it should show you how it is used.

<script lang="ts">
import { defineComponent, PropType } from 'vue';
import { Editor } from "@tiptap/vue-2";
import EditorMenuButton from "./EditorMenuButton.vue";

export const sizes = [
  "8",
  "10",
  "12",
  "14",
  "16",
  "18",
  "20",
  "24",
  "30",
  "36",
  "48",
  "60",
  "72",
];

export default defineComponent({
  name: "FontTypeDropdown",
  components: { EditorMenuButton },
  props: {
    editor: {
      type: Object as PropType<Editor>,
      required: true,
    },
  },
  setup() {
    return { sizes };
  },
});
</script>

<template>
  <v-menu bottom close-on-content-click offset-y>
    <template #activator="{ on, attrs }">
      <EditorMenuButton
        icon="$fontSize"
        tooltip="Font Size"
        v-bind="attrs"
        v-on="on"
      />
    </template>
    <v-list dense>
      <v-list-item @click="editor.chain().focus().unsetFontSize().run()">
        default
      </v-list-item>
      <v-list-item
        v-for="size in sizes"
        :key="size"
        :class="{
          active: editor.isActive('textStyle', { fontSize: `${size}px` }),
        }"
        @click="editor.chain().focus().setFontSize(`${size}px`).run()"
      >
        <v-list-item-content>{{ size }}</v-list-item-content>
      </v-list-item>
    </v-list>
  </v-menu>
</template>

<style lang="scss" scoped>
.active {
  background-color: rgba(0, 0, 0, 0.1);
}
</style>

@aberkayk
Copy link

Thank you for your response. Here is how I implemented to my code in my Nextjs project with Shadcn.

const fontSizes = Array.from({ length: 31 }, (_, i) => ${i + 6}px);

const Toolbar = ({ content, editor }: Props) => {
if (!editor) return null;
return (



{/* Font Size Button */}
<Select
onValueChange={(value) => {
editor.commands.setFontSize(value);
}}
>





{fontSizes.map((size, index) => (

{size}

))}




);
};
......rest of the code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment