Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Markdown editor unregister tooltip plugin #4383

Merged
merged 8 commits into from
Jan 26, 2021

Conversation

K-Kumar-01
Copy link
Contributor

@K-Kumar-01 K-Kumar-01 commented Dec 15, 2020

Issue number #4239
Ability to unregister the tooltip plugin added
Updated the editor example doc (mardowm_editor_example.js) to show how to use it

Summary

Provide a detailed summary of your PR. Explain how you arrived at your solution. If it includes changes to UI elements include a screenshot or gif.

Checklist

  • Check against all themes for compatibility in both light and dark modes
  • Checked in mobile
  • Checked in Chrome, Safari, Edge, and Firefox
    - [ ] Props have proper autodocs
  • Added Updated documentation
    - [ ] Checked Code Sandbox works for the any docs examples
    - [ ] Added or updated jest tests
  • Checked for breaking changes and labeled appropriately
    - [ ] Checked for accessibility including keyboard-only and screenreader modes
  • A changelog entry exists and is marked appropriately

Issue number 4239
Ability to unregister the tooltip plugin added
Updated the editor example doc to show how to use it
@cla-checker-service
Copy link

cla-checker-service bot commented Dec 15, 2020

💚 CLA has been signed

@kibanamachine
Copy link

Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually?

@elizabetdev
Copy link
Contributor

Hi @K-Kumar-01, thanks for contributing to EUI!

Can you please sign the Contributor agreement using the email associated with your GitHub account?

@elizabetdev
Copy link
Contributor

jenkins test this

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_4383/

@K-Kumar-01
Copy link
Contributor Author

Hi @K-Kumar-01, thanks for contributing to EUI!

Can you please sign the Contributor agreement using the email associated with your GitHub account?

In the Title field, I have put my name for now, as I didn't know what to put there.

@chandlerprall chandlerprall self-requested a review December 16, 2020 16:48
@chandlerprall
Copy link
Contributor

chandlerprall commented Dec 16, 2020

Thanks for the PR! I think we need to broaden the change to account for other (future) plugins, and not be specific to the tooltip UI.

If you look at src/components/markdown_editor/plugins/markdown_default_plugins.tsx there are two existing functions providing plugin arrays: getDefaultEuiMarkdownParsingPlugins and getDefaultEuiMarkdownProcessingPlugins. We should add a third one to return a default uiPlugins array, [MarkdownTooltip.plugin]. EuiMarkdownEditor would only need to be changed to not inject the tooltip plugin, instead passing uiPlugins directly to the toolbar component - maybe some extra work here depending on the following conversation:

@timroes this would be a breaking change, which is okay, but I think we could get by with a deprecation here by adding a flag to the return uiPlugins array which the editor could check for - if it's missing, it could continue injecting the tooltip button. Thoughts?

getDefaultEuiMarkdownUiPlugins = () => {
  const plugins = [MarkdownTooltip.plugin];
  plugins.__pregenerated = true;
  return plugins;
}

@K-Kumar-01
Copy link
Contributor Author

Thanks for the PR! I think we need to broaden the change to account for other (future) plugins, and not be specific to the tooltip UI.

If you look at src/components/markdown_editor/plugins/markdown_default_plugins.tsx there are two existing functions providing plugin arrays: getDefaultEuiMarkdownParsingPlugins and getDefaultEuiMarkdownProcessingPlugins. We should add a third one to return a default uiPlugins array, [MarkdownTooltip.plugin]. EuiMarkdownEditor would only need to be changed to not inject the tooltip plugin, instead passing uiPlugins directly to the toolbar component - maybe some extra work here depending on the following conversation:

@timroes this would be a breaking change, which is okay, but I think we could get by with a deprecation here by adding a flag to the return uiPlugins array which the editor could check for - if it's missing, it could continue injecting the tooltip button. Thoughts?

getDefaultEuiMarkdownUiPlugins = () => {
  const plugins = [MarkdownTooltip.plugin];
  plugins.__pregenerated = true;
  return plugins;
}

@chandlerprall
I will update my PR after the suggestion of @timroes, as you stated.

@K-Kumar-01
Copy link
Contributor Author

Thanks for the PR! I think we need to broaden the change to account for other (future) plugins, and not be specific to the tooltip UI.

If you look at src/components/markdown_editor/plugins/markdown_default_plugins.tsx there are two existing functions providing plugin arrays: getDefaultEuiMarkdownParsingPlugins and getDefaultEuiMarkdownProcessingPlugins. We should add a third one to return a default uiPlugins array, [MarkdownTooltip.plugin]. EuiMarkdownEditor would only need to be changed to not inject the tooltip plugin, instead passing uiPlugins directly to the toolbar component - maybe some extra work here depending on the following conversation:

@timroes this would be a breaking change, which is okay, but I think we could get by with a deprecation here by adding a flag to the return uiPlugins array which the editor could check for - if it's missing, it could continue injecting the tooltip button. Thoughts?

getDefaultEuiMarkdownUiPlugins = () => {
  const plugins = [MarkdownTooltip.plugin];
  plugins.__pregenerated = true;
  return plugins;
}

@timroes
Any updates here?

@chandlerprall
Copy link
Contributor

A lot of us are now on holiday through the end of the year, and those remaining will start taking time this week. Since Tim's not here, let's go with my proposed setup to avoid a breaking change and see how that feels. 😁

@K-Kumar-01
Copy link
Contributor Author

@chandlerprall
I had a doubt here.

EuiMarkdownEditor would only need to be changed to not inject the tooltip plugin, instead passing uiPlugins directly to the toolbar component

Can you please explain what the above sentence means. I am unable to understand what we have to do here.

@chandlerprall
Copy link
Contributor

Sure thing!

Right now, EuiMarkdownEditor receives an array of UI plugins https://github.com/elastic/eui/blob/master/src/components/markdown_editor/markdown_editor.tsx#L158

It then mixes that array with the internally-defined tooltip plugin https://github.com/elastic/eui/blob/master/src/components/markdown_editor/markdown_editor.tsx#L179

This prevents an application from removing the tooltip's toolbar UI, even if the tooltip processing has been disabled. The uiPlugins prop needs to be updated to work the same way parsingPluginList and processingPluginList are, which default to an internally-built list but can be fully overridden. One extra step is needed though, as doing this blindly for uiPlugins would not be backwards compatible:

uiPlugins will need to still be enhanced with MarkdownTooltip.plugin if the uiPlugins array did not originate from EUI's internal plugin array. This modifies the quote,

EuiMarkdownEditor would only need to be changed to not inject the tooltip plugin, need to inject the tooltip plugin if the array source is external to EUI, instead otherwise passing uiPlugins directly to the toolbar component

Let me know if that's still not clear!

@K-Kumar-01
Copy link
Contributor Author

Sure thing!

Right now, EuiMarkdownEditor receives an array of UI plugins https://github.com/elastic/eui/blob/master/src/components/markdown_editor/markdown_editor.tsx#L158

It then mixes that array with the internally-defined tooltip plugin https://github.com/elastic/eui/blob/master/src/components/markdown_editor/markdown_editor.tsx#L179

This prevents an application from removing the tooltip's toolbar UI, even if the tooltip processing has been disabled. The uiPlugins prop needs to be updated to work the same way parsingPluginList and processingPluginList are, which default to an internally-built list but can be fully overridden. One extra step is needed though, as doing this blindly for uiPlugins would not be backwards compatible:

uiPlugins will need to still be enhanced with MarkdownTooltip.plugin if the uiPlugins array did not originate from EUI's internal plugin array. This modifies the quote,

EuiMarkdownEditor would only need to be changed to not inject the tooltip plugin, need to inject the tooltip plugin if the array source is external to EUI, instead otherwise passing uiPlugins directly to the toolbar component

Let me know if that's still not clear!

@chandlerprall
Thanks for the explanation. I understood most of the concepts, though I still have a few doubts.

  1. The parsingPluginList is passed as a pluggable list prop as far as I understand the code with default value as defaultParsingPluginList. Is the overriding you refer to here means passing it as props? Same for processingPluginList.
  2. If overriding is the case above, then we should pass uiPlugins as a default value of internally built plugins if the user has not given any uiPlugins. In case there are uiPlugins passed, then also the tooltip plugin will be there unlike the above two, with the capability to be removed. Am I on the right track?

uiPlugins will need to still be enhanced with MarkdownTooltip.plugin if the uiPlugins array did not originate from EUI's internal plugin array.

Still not able to comprehend this part

@chandlerprall
Copy link
Contributor

parsingPluginList and processingPluginList are correctly setup and represent what uiPlugins should have been from the beginning: a completely customizable list passed unmodified. The primary goal here is to make uiPlugins work like the other two do.

The part that's confusing here is to avoid making this a backwards-compatible change. For example, right now if I provide my own uiPlugins array the component also injects MarkdownTooltip.plugin. Switching uiPlugins to 100% the same pattern as the other two plugin props, that functionality is dropped. So I propose keeping track of if the uiPlugins array was created by the (to be created) getDefaultEuiMarkdownUiPlugins function, and if not then continue to inject the tooltip plugin.

Something like,

function getDefaultEuiMarkdownUiPlugins() {
  const array = [MarkdownTooltip.plugin];
  array.__originatedFromEui = true;
  return array;
}

... inside **EuiMarkdownEditor**

const toolbarPlugins = [...uiPlugins];
if (uiPlugins.__originatedFromEui !== true) toolbarPlugins.unshift(MarkdownTooltip.plugin);

This allows existing implementations to continue working, while allowing new implementations to call getDefaultEuiMarkdownUiPlugins and then remove the plugin.

@timroes
Copy link
Contributor

timroes commented Jan 11, 2021

@chandlerprall I unfortunately also had a couple of issues understanding the desired solution, so let me make sure that I understand it:

I am not really seeing how the proposed solution would prevent a breaking change? In the code you outlined above when a user passes in a custom array to uiPlugins, the code runs through the second part you outlined, it will detect that uiPlugins.__originatedFromEui is not true, and thus remove the MarkdownTooltip.plugin. But that means we're breaking behavior?

E.g. a user had the following code:

<EuiMarkdownEditor uiPlugins={[myFancyEmojiPlugin]} />

Before that they would get the fancy emoji plugin AND the the tooltip plugin, after that change they would only get the emoji plugin?

I am sorry for all the clarification, but could you potentially outline the consuming code, that you want to prevent breaking by that solution? (Btw I am not against a breaking change at all, just trying to understand the solution.)

@chandlerprall
Copy link
Contributor

it will detect that uiPlugins.__originatedFromEui is not true, and thus remove the MarkdownTooltip.plugin

Other way around, it'll detect uiPlugins.__originatedFromEui is not true and then inject the plugin.

@timroes
Copy link
Contributor

timroes commented Jan 12, 2021

Meaning, if youa ctually want to get rid of it, you'll need to do something like the following?

const plugins = getDefaultEuiMarkdownUiPlugins();
plugins.splice(0, plugins.length);
plugins.push(yourPlugin);
<EuiMarkdownEditor uiPlugins={plugins} />

@chandlerprall
Copy link
Contributor

Meaning, if youa ctually want to get rid of it, you'll need to do something like the following?

Correct. We'd mark the old functionality (injecting the tooltip) as deprecated and console.warn when it happens, but gives us room to make the change without being breaking.

@K-Kumar-01
Copy link
Contributor Author

@chandlerprall @timroes
I will try to implement the functionality as discussed in the comments and let you know if I face any difficulty.
Thanks for the clarification. :)

@K-Kumar-01
Copy link
Contributor Author

K-Kumar-01 commented Jan 15, 2021

@chandlerprall
I implemented the above functionality and the code worked well. However at the time of commit I am getting this error.
Screenshot from 2021-01-15 13-40-00
I tried understanding the error and got to know that it is due to

Property '__originatedFromEui' does not exist on type '{ name: string; button: { label: string; iconType: string; }; formatting: { prefix: string; suffix: string; trimFirst: boolean; }; helpText: Element; }[]'

VS Code is showing some quick fixed though it changes the typescript lib file
Screenshot from 2021-01-15 13-43-53
Should I go for this fix or is there any other method possible?

@chandlerprall
Copy link
Contributor

Let's tell TS to ignore the problem both where you set it on the array and then check for it later (which I assume will give the same error)

// @ts-ignore __originatedFromEui is a custom property
theArray.__originatedFromEui = true;

Added the ability to unregsiter inbuilt UI plugins
Addresses issue 4239

Signed-off-by: k-kumar-01 <[email protected]>
Signed-off-by: k-kumar-01 <[email protected]>
@K-Kumar-01
Copy link
Contributor Author

Let's tell TS to ignore the problem both where you set it on the array and then check for it later (which I assume will give the same error)

// @ts-ignore __originatedFromEui is a custom property
theArray.__originatedFromEui = true;

@chandlerprall
I have made the changes to remove the tooltip plugin.
Let me know if there are any changes required.

@chandlerprall
Copy link
Contributor

Tested, and it is working as expected. Thanks! Couple of items left:

  • The default value for uiPlugins should come from getDefaultEuiMarkdownUiPlugins, similar to defaults for parsingPluginList and processingPluginList
  • markdown_editor_with_plugins.js relies on this tooltip auto-inclusion and should be updated to use getDefaultEuiMarkdownUiPlugins
  • When adding the tooltip plugin let's include a deprecation message:
console.warn('Deprecation warning: uiPlugins passed to EuiMarkdownEditor does not include the tooltip plugin, which has been added for you. This automatic inclusion has been deprecated and will be removed in the future, see https://github.com/elastic/eui/pull/4383')

Default UI Plugins initialized
Warning added on injecting tooltip plugin

Signed-off-by: k-kumar-01 <[email protected]>
@K-Kumar-01
Copy link
Contributor Author

console.warn('Deprecation warning: uiPlugins passed to EuiMarkdownEditor does not include the tooltip plugin, which has been added for you. This automatic inclusion has been deprecated and will be removed in the future, see #4383')

@chandlerprall
If I am right, we should do this:

 if (!uiPlugins.__originatedFromEui) {
      toolbarPlugins.unshift(MarkdownTooltip.plugin);
      console.warn(
        'Deprecation warning: uiPlugins passed to EuiMarkdownEditor does not include the tooltip plugin, which has been added for you. This automatic inclusion has been deprecated and will be removed in the future, see https://github.com/elastic/eui/pull/4383'
      );
    }

I have added a PR making the above changes. Let me know if there are any changes required. :)

@chandlerprall
Copy link
Contributor

Changes look good, I pushed an entry CHANGELOG.md & an update to the markdown plugin example page to use the new method. Will merge this after CI passes - jenkins test this

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_4383/

@chandlerprall
Copy link
Contributor

looks like a flaky test run, jenkins test this

@kibanamachine
Copy link

Preview documentation changes for this PR: https://eui.elastic.co/pr_4383/

Copy link
Contributor

@chandlerprall chandlerprall left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay in merging @K-Kumar-01 , everything looks good; thanks for making these changes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants