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

feat(ui-markdown-editor): inline wysiwyg - #360 #361

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

d-e-v-esh
Copy link
Contributor

Closes #360

This PR will let people directly write formatted text with the help of markdown shortcuts.

It adds the following features:

  1. Code Inline → `code inline` → code inline
  2. Italic Text → *italic text* or _italic text_ → italic text
  3. Bold Text → **bold text** or => __bold text__ → bold text
  4. Bold and Italic Text → ***bold and italic text*** or ___bold and italic text___ → bold and italic text

Changes

Functions added:

  • matchCodeInline => Implements the markdown shortcuts for inline code
  • matchBoldAndItalic => Implements the markdown shortcuts for italic, bold and bold + italic text.
  • insertFormattedInlineText => This function is used in both the above functions. It is used to format and insert the formatted text in the right place.

Bugs and Improvements

  • A bug was also fixed from the previous PR where all the matching functions would run on every keypress as soon as the Regex matched, now the matching functions run only after the spacebar is pressed. This makes using the shortcuts much more easier and convenient.
  • Removed editor and currentLine arguments from functions as those values are available in the whole file and can be fetched directly by those functions.

Screenshots or Video

2021-12-21.20-40-30.mp4

Related Issues

Author Checklist

  • Ensure you provide a DCO sign-off for your commits using the --signoff option of git commit.
  • Vital features and changes captured in unit and/or integration tests
  • Commits messages follow AP format
  • Extend the documentation, if necessary
  • Merging to master from fork:branchname
  • Manual accessibility test performed
    • Keyboard-only access, including forms
    • Contrast at least WCAG Level A
    • Appropriate labels, alt text, and instructions

@jolanglinais
Copy link
Member

Just an initial thought from watching the recording: I think it would be better to have the text formatted after the final character of the formatting text rather than the space after.

So instead "bold" turning into "bold" when the cursor (_) is in this location:

typing *bold* _

Have "bold" turn into "bold" when the cursor (_) is in this location:

typing *bold*_

Copy link
Member

@jolanglinais jolanglinais left a comment

Choose a reason for hiding this comment

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

Really great stuff here!

Some initial thoughts. After going through these, could you also format the code in the files (especially packages/ui-markdown-editor/src/utilities/matchCases.js) so it's a bit easier to go through?

I likely have more thoughts, but I think with the formatting and my already made comments, it's getting a bit hectic so I'll add more after you address these comments.

@@ -4,6 +4,8 @@ const MISC_CONSTANTS = {
DROPDOWN_NORMAL: 'Normal',
};

export const SPACE_BAR = " ";
Copy link
Member

Choose a reason for hiding this comment

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

Slightly nit-picky, but maybe this variable could be SPACE_CHARACTER instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed it to a SPACE_CHARACTER. 👍

Comment on lines 18 to 23
switch (ev.key) {
case SPACE_BAR:
matchCases(editor, currentLine);
break;
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Do you expect there to be other cases? If not, I think we could do this without a switch case to be more simple.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I changed it to a simple if-else statement as I don't think there will be more cases for it right now.


const currentLine = currentNode.text

onkeyup = (ev) => {
Copy link
Member

Choose a reason for hiding this comment

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

Could this be better handled in our onKeyDown handler instead of in the withText plugin?

Comment on lines 37 to 44
/**
*
* @param {string} textToInsert The text that we want to format
* @param {Object} textFormats This is the format style of the text (bold, italic, code) we want to apply or remove as the key in an object
* and a boolean as the value. i.e. `{ bold: true }`
* @param {Integer} markdownCharacters The number of markdown characters that the user has to type to trigger WYSIWYG
*/
const insertFormattedInlineText = (textToInsert, textFormats, markdownCharacters) => {
Copy link
Member

Choose a reason for hiding this comment

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

Could insertFormattedInlineText be defined outside of matchCases?

Copy link
Contributor Author

@d-e-v-esh d-e-v-esh Dec 22, 2021

Choose a reason for hiding this comment

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

Should I put it outside the matchCases function or outside the matchCases file?

Copy link
Member

Choose a reason for hiding this comment

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

I think outside the function, probably keep it in this file for now.

@d-e-v-esh
Copy link
Contributor Author

d-e-v-esh commented Dec 22, 2021

Really great stuff here!

Some initial thoughts. After going through these, could you also format the code in the files (especially packages/ui-markdown-editor/src/utilities/matchCases.js) so it's a bit easier to go through?

I likely have more thoughts, but I think with the formatting and my already made comments, it's getting a bit hectic so I'll add more after you address these comments.

@irmerk The formatting was looking normal in VSCode but for some reason, it started to look weird after I pushed it here, so I ran it through prettier and now it looks normal.

@d-e-v-esh
Copy link
Contributor Author

d-e-v-esh commented Dec 22, 2021

Just an initial thought from watching the recording: I think it would be better to have the text formatted after the final character of the formatting text rather than the space after.

So instead "bold" turning into "bold" when the cursor (_) is in this location:

typing *bold* _

Have "bold" turn into "bold" when the cursor (_) is in this location:

typing *bold*_

@irmerk I think the two ways of executing shortcuts that you mentioned above have very different implementations. I implemented the (1) one which seemed a bit easier for me.

How it works here is:

  1. When the function runs on the press of SPACE_CHARATER, the matchBoldAndItalic simply counts the asterisks (*) or underscores ( _ ) at the end of that matched regex, i.e.

    If I write this:

    This is **bold text**
    

    The matched regex will be:

    **bold text**
    

    And the function will count 2 as the number of asterisks at the end **bold text|**| and turn it in bold text.

  2. If I just remove that onkeyup condition, and run the matchCases function on every keypress then it will not work.

    If I write this: =>

    This is **bold text**

    Before it even becomes into bold text, it will match the italicMatchCase and turn the text into italic text and the result will be something like:

    This is *bold text.

This will happen before we even enter the second asterisk at the end. It will just take *bold text from the **bold text* and convert it to italic.


For it to behave how you mentioned (2), I think I'll probably have to scrap this method and implement it the other way.
I think it'll work like how stack data structure works in a compiler, where it'll keep track of the number of * and _ that has been entered onto the current line.

In this implementation, we will count the * and _ at the beginning |**|bold text** of the word instead of the end **bold text|**| and appropriately run those matching functions.

Let me know what you think about it or if you think there is some other way. 👍

@jolanglinais
Copy link
Member

Apologies for the delay in responding.

This is interesting, I hadn't thought of that. **bold** will turn italic because of the first * after bold will be registered and we'll never be able to get to the second * to actually make it bold. Hmm... It would work if we used _ for italic:

_word_ = word
*bold* = bold

But we're working with CommonMark.

I think I'd like a UX perspective here before proceeding in any direction, if you can look at this @Michael-Grover.

@d-e-v-esh
Copy link
Contributor Author

d-e-v-esh commented Jan 16, 2022

@irmerk Yes, that'll be great. I'll wait for that before I update anything 👍

Copy link
Contributor

@dselman dselman left a comment

Choose a reason for hiding this comment

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

Could this be moved to its own function - like withShortcuts does in the Slate example?
https://github.com/ianstormtaylor/slate/blob/main/site/examples/markdown-shortcuts.tsx

I also notice that the Slate example covers more shortcuts than this does. They also hook into insertText which I suspect means that the code will also work on copy/paste. Thoughts?

@d-e-v-esh
Copy link
Contributor Author

d-e-v-esh commented Jan 20, 2022

@dselman

Could this be moved to its own function - like withShortcuts does in the Slate example? https://github.com/ianstormtaylor/slate/blob/main/site/examples/markdown-shortcuts.tsx

Yes, I think that it is a good idea. We can do that.

I also notice that the Slate example covers more shortcuts than this does.

This PR just includes the shortcuts that are performed on inline text, will add more shortcuts once this gets approved.

They also hook into insertText which I suspect means that the code will also work on copy/paste. Thoughts?

These inline shortcuts also hook into the insertText so they will totally work on copy/paste.

Would love to know what others think?

@jolanglinais
Copy link
Member

I agree that we can iterate on more shortcuts after this gets merged in. I think a withShortcuts approach would be great.

@d-e-v-esh
Copy link
Contributor Author

I agree that we can iterate on more shortcuts after this gets merged in. I think a withShortcuts approach would be great.

Thanks for the feedback.
I'll update the PR with a withShortcuts approach soon. 👍

@d-e-v-esh
Copy link
Contributor Author

@irmerk @dselman I implemented it with the withShortcuts approach. Does it need any more changes?

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

Successfully merging this pull request may close these issues.

Inline Markdown Shortcuts (WYSIWYG)
3 participants