ckeditor / ckeditor5

Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.
https://ckeditor.com/ckeditor-5
Other
9.54k stars 3.7k forks source link

How to make font family/size dropdown display their current value in the button? #2282

Open Sora2455 opened 6 years ago

Sora2455 commented 6 years ago

In issue ckeditor/ckeditor5#2277, it was decided that the font family/size options should be implemented as Buttons, with the only way to see the currently-selected family/size clicking the button.

Having made the switch from CkEditor4 to CkEditor5, we're already getting complaints about this.

I understand that it might make the UI cluttered, but would it be possible to expose the current Button version of the selector as well as a Dropdown implementation as different toolbar config options? Similar to how the Alignment feature has both a button-based and dropdown-based implementation?


If you'd like these dropdowns to be available in the official plugin add 👍 to this ticket.

jodator commented 6 years ago

Hi @Sora2455 - thanks for reporting. We're adding features/extending current one based on feedback.

Right now I don't recall similar request so I don't know if we're going to add this in near future but fortunately the CKEditor5's API allows to extend existing components. You'd need only to create a custom CKEditor 5 build with a plugin which will create does components:

for font family:

this.editor.ui.componentFactory.add( 'fontFamilyDropdown', () => {
    const editor = this.editor;
    const t = editor.t;

    const command = editor.commands.get( 'fontFamily' );

    // Use original fontFamily button - we only changes its behavior.
    const dropdownView = editor.ui.componentFactory.create( 'fontFamily' );

    // Show label on dropdown's button.
    dropdownView.buttonView.set( 'withText', true );

    // To hide the icon uncomment below.
    // dropdownView.buttonView.set( 'icon', false );

    // Bind dropdown's button label to fontFamily value.
    dropdownView.buttonView.bind( 'label' ).to( command, 'value', value => {
        // If no value is set on the command show 'Default' text.
        // Use t() method to make that string translatable.
        return value ? value : t( 'Default' );
    } );

    return dropdownView;
} );

for font size:

this.editor.ui.componentFactory.add( 'fontSizeDropdown', () => {
    const editor = this.editor;
    const t = editor.t;

    const command = editor.commands.get( 'fontSize' );

    // Use original fontSize button - we only changes its behavior.
    const dropdownView = editor.ui.componentFactory.create( 'fontSize' );

    // Show label on dropdown's button.
    dropdownView.buttonView.set( 'withText', true );

    // To hide the icon uncomment below.
    // dropdownView.buttonView.set( 'icon', false );

    // Bind dropdown's button label to fontSize value.
    dropdownView.buttonView.bind( 'label' ).to( command, 'value', value => {
        // If no value is set on the command show 'Default' text.
        // Use t() method to make that string translatable.
        return value ? value : t( 'Default' );
    } );

    return dropdownView;
} );

Then use it in toolbar configuration:

ClassicEditor
    .create( document.querySelector( '#editor' ), {
        toolbar: [
            'heading', '|', 'fontFamilyDropdown', '|', 'fontSizeDropdown', '|'
        ]
    } )

The result below: selection_058

Sora2455 commented 6 years ago

Thanks for the code samples, @jodator! They look fantastic!

wuguokai commented 5 years ago

Hi! I have the same demand . It is so cool. Where this code should add? @Sora2455 @jodator

this.editor.ui.componentFactory.add( 'fontSizeDropdown', () => {
    const editor = this.editor;
    const t = editor.t;

    const command = editor.commands.get( 'fontSize' );

    // Use original fontSize button - we only changes its behavior.
    const dropdownView = editor.ui.componentFactory.create( 'fontSize' );

    // Show label on dropdown's button.
    dropdownView.buttonView.set( 'withText', true );

    // To hide the icon uncomment below.
    // dropdownView.buttonView.set( 'icon', false );

    // Bind dropdown's button label to fontSize value.
    dropdownView.buttonView.bind( 'label' ).to( command, 'value', value => {
        // If no value is set on the command show 'Default' text.
        // Use t() method to make that string translatable.
        return value ? value : t( 'Default' );
    } );

    return dropdownView;
} );
jodator commented 5 years ago

@wuguokai: check my response in your question.

rickycai-2020 commented 4 years ago

Hi @Sora2455 - thanks for reporting. We're adding features/extending current one based on feedback.

Right now I don't recall similar request so I don't know if we're going to add this in near future but fortunately the CKEditor5's API allows to extend existing components. You'd need only to create a custom CKEditor 5 build with a plugin which will create does components:

for font family:

this.editor.ui.componentFactory.add( 'fontFamilyDropdown', () => {
  const editor = this.editor;
  const t = editor.t;

  const command = editor.commands.get( 'fontFamily' );

  // Use original fontFamily button - we only changes its behavior.
  const dropdownView = editor.ui.componentFactory.create( 'fontFamily' );

  // Show label on dropdown's button.
  dropdownView.buttonView.set( 'withText', true );

  // To hide the icon uncomment below.
  // dropdownView.buttonView.set( 'icon', false );

  // Bind dropdown's button label to fontFamily value.
  dropdownView.buttonView.bind( 'label' ).to( command, 'value', value => {
      // If no value is set on the command show 'Default' text.
      // Use t() method to make that string translatable.
      return value ? value : t( 'Default' );
  } );

  return dropdownView;
} );

for font size:

this.editor.ui.componentFactory.add( 'fontSizeDropdown', () => {
  const editor = this.editor;
  const t = editor.t;

  const command = editor.commands.get( 'fontSize' );

  // Use original fontSize button - we only changes its behavior.
  const dropdownView = editor.ui.componentFactory.create( 'fontSize' );

  // Show label on dropdown's button.
  dropdownView.buttonView.set( 'withText', true );

  // To hide the icon uncomment below.
  // dropdownView.buttonView.set( 'icon', false );

  // Bind dropdown's button label to fontSize value.
  dropdownView.buttonView.bind( 'label' ).to( command, 'value', value => {
      // If no value is set on the command show 'Default' text.
      // Use t() method to make that string translatable.
      return value ? value : t( 'Default' );
  } );

  return dropdownView;
} );

Then use it in toolbar configuration:

ClassicEditor
  .create( document.querySelector( '#editor' ), {
      toolbar: [
          'heading', '|', 'fontFamilyDropdown', '|', 'fontSizeDropdown', '|'
      ]
  } )

The result below: selection_058

How could I apply the this code block into a build-from-source CKEditor 5

hagaygo commented 9 months ago

Any updated solution for this issue ?

Some links on the posts here are not valid anymore, issue is still open so it seems there is no "built in" solution for font size (our main issue) toolbar.